Env setupu¶

In [1]:
import scanpy as sc, anndata as ad, numpy as np, pandas as pd
from scipy import sparse
import matplotlib.pyplot as plt
import plotly.express as px
from anndata import AnnData
from sklearn.neighbors import KernelDensity
import random
from matplotlib import pylab
import warnings
import scanpy.external as sce
import pyranges as pr
import yaml
from matplotlib.colors import TwoSlopeNorm
from pyliftover import LiftOver


import seaborn as sns
import os
import sys

warnings.filterwarnings('ignore')
In [2]:
import anndata2ri
import rpy2.rinterface_lib.callbacks
import logging
In [3]:
rpy2.rinterface_lib.callbacks.logger.setLevel(logging.ERROR)
In [4]:
anndata2ri.activate()
In [5]:
%load_ext rpy2.ipython
In [6]:
sc.settings.verbosity = 3  
sc.logging.print_header()
nprocs=4
np.random.seed(0)
with open("../data/resources/rcParams.yaml") as f:
    rcParamsDict = yaml.full_load(f)
    for k in rcParamsDict["rcParams"]:
        print("{} {}".format(k,rcParamsDict["rcParams"][k]))
        plt.rcParams[k] = rcParamsDict["rcParams"][k]
    for k1 in set(list(rcParamsDict)).difference(set(["rcParams"])):
        print("{} {}".format(k1,rcParamsDict[k1]))
scanpy==1.9.3 anndata==0.8.0 umap==0.5.1 numpy==1.20.3 scipy==1.10.1 pandas==2.0.3 scikit-learn==1.3.2 statsmodels==0.13.5 python-igraph==0.9.1 louvain==0.7.0 leidenalg==0.8.3 pynndescent==0.5.12
figure.dpi 80
savefig.dpi 500
figure.figsize [10, 10]
axes.facecolor None
figure.facecolor None
dotSize 20

Configure paths¶

In [7]:
outdir = "../data/output"
homeDir = os.getenv("HOME")

with open("../data/resources/iPSC_lines_map.yaml", 'r') as f:
    iPSC_lines_map = yaml.load(f, Loader=yaml.FullLoader)["lines"]
colorsmap = dict(zip([i["newName"] for i in iPSC_lines_map.values()],[i["color"] for i in iPSC_lines_map.values()]))


figDir = "./figures"
if not os.path.exists(figDir):
   # Create a new directory because it does not exist
   os.makedirs(figDir)


    
#tradeSeqUtilsPath = "/opt/tradeSeq_utils.R"
tradeSeqUtilsPath = "/opt/tradeSeq_utils.R"

vcfPath = "../data/jointGenotype.g.vcf"

gtfPath = "../data/resources/genes.gtf"

# sc eQTLs from jerber et al https://doi.org/10.1038/s41588-021-00801-6
scEqtlsJerber = pd.read_csv("../data/resources/Jerber_scASE.tsv", sep="\t")


sys.path.insert(1, homeDir+"/utils/")
from PurgeAdata import *

var setting¶

In [8]:
branchTag = "Migrating"
endpoint = "endpoint_MigratingNeurons"
markers = ["RELN","PAX6","CBLN1","MKI67","FOXP1"]
min_cells = 50
MultiTPTstages = ["early","mid"]
binWidthRate = .05
ResamplingIterations = 50
leidenOrder = ["ProliferatingProgenitors", 'RadialGliaProgenitors', 'Neurons','MigratingNeurons']
In [9]:
BranchBCs = sc.read_h5ad(outdir+"/adatas/adataPaga.h5ad")

sc.pl.draw_graph(BranchBCs[BranchBCs.obs[endpoint] == 1], color = ["cellID_newName","leidenAnnotated","dataset"],size =  rcParamsDict["dotSize"],add_outline=True, outline_width=(0.2, 0.05), vmin='p2',vmax='p98', wspace=.4, ncols=2)

BranchBCs = BranchBCs.obs_names[BranchBCs.obs[endpoint] == 1].tolist()

harmonyTheta = 1

HVGs = pd.read_csv(outdir+"/HVG_list_intersection_Curated_"+branchTag+"_PagaTest.txt", sep = "\t")["HVG"]

Branch specific pre-processing¶

In [10]:
adataBranch = sc.read_h5ad(outdir+'/adatas/MultiplexingPreprocessing_unscaled.h5ad')[BranchBCs]
adataBranch.obs["leidenAnnotated"] =  sc.read_h5ad(outdir+"/adatas/ClusterAnnotated_Base_filt.h5ad")[adataBranch.obs_names].obs["leidenAnnotated"]
adataBranch.uns["leidenAnnotated_colors"] =  sc.read_h5ad(outdir+"/adatas/adataPaga.h5ad")[adataBranch.obs_names].uns["leidenAnnotated_colors"]
goodcls = adataBranch.obs.groupby(["leidenAnnotated"]).size()[adataBranch.obs.groupby(["leidenAnnotated"]).size() >= 50].index.tolist()
adataBranch = adataBranch[adataBranch.obs["leidenAnnotated"].isin(goodcls)]


adataBranch.layers["unscaled"] = adataBranch.X.copy()


sc.pp.normalize_total(adataBranch, target_sum=1e4)

sc.pp.log1p(adataBranch)
adataBranch.raw = adataBranch



adataBranch = adataBranch[:,HVGs]
adataBranch.var["highly_variable"] = True
#sc.pp.highly_variable_genes(adataBranch, min_mean=0.0125, max_mean=5, min_disp=0.5, batch_key = "dataset")

sc.pp.regress_out(adataBranch, ['total_counts','pct_counts_mt'], n_jobs=4)
sc.pp.scale(adataBranch, zero_center=False)
#adataBranch.X = adataBranch.X + np.abs(adataBranch.X.min())
normalizing counts per cell
    finished (0:00:00)
regressing out ['total_counts', 'pct_counts_mt']
    sparse input is densified and may lead to high memory use
    finished (0:00:59)
In [11]:
sc.tl.pca(adataBranch, svd_solver='arpack', use_highly_variable=True)
sce.pp.harmony_integrate(adataBranch, 'dataset', max_iter_harmony=20,adjusted_basis="X_pca",random_state = 0, theta = harmonyTheta, lamb = 2)
sc.pp.neighbors(adataBranch,use_rep="X_pca",n_neighbors=50, n_pcs=10, random_state=0)

sc.tl.umap(adataBranch, random_state=0)
computing PCA
    on highly variable genes
    with n_comps=50
    finished (0:00:03)
2024-06-04 10:12:10,954 - harmonypy - INFO - Iteration 1 of 20
2024-06-04 10:12:12,829 - harmonypy - INFO - Iteration 2 of 20
2024-06-04 10:12:14,465 - harmonypy - INFO - Iteration 3 of 20
2024-06-04 10:12:16,429 - harmonypy - INFO - Iteration 4 of 20
2024-06-04 10:12:18,365 - harmonypy - INFO - Iteration 5 of 20
2024-06-04 10:12:20,309 - harmonypy - INFO - Iteration 6 of 20
2024-06-04 10:12:21,736 - harmonypy - INFO - Iteration 7 of 20
2024-06-04 10:12:23,142 - harmonypy - INFO - Iteration 8 of 20
2024-06-04 10:12:23,946 - harmonypy - INFO - Iteration 9 of 20
2024-06-04 10:12:24,764 - harmonypy - INFO - Iteration 10 of 20
2024-06-04 10:12:26,354 - harmonypy - INFO - Iteration 11 of 20
2024-06-04 10:12:27,157 - harmonypy - INFO - Converged after 11 iterations
computing neighbors
    finished: added to `.uns['neighbors']`
    `.obsp['distances']`, distances for each pair of neighbors
    `.obsp['connectivities']`, weighted adjacency matrix (0:00:04)
computing UMAP
    finished: added
    'X_umap', UMAP coordinates (adata.obsm) (0:00:24)
In [12]:
with open("../data/resources/CelltypeColors.yaml") as f:
    CelltypeColors = yaml.full_load(f)["leidenAnnotated_colors"]

adataBranch.uns["leidenAnnotated_colors"] = np.array([CelltypeColors[i] for i in adataBranch.obs.leidenAnnotated.cat.categories.tolist()])

sc.pl.pca(adataBranch, color = ["dataset","stage",'leidenAnnotated'], size = rcParamsDict["dotSize"],add_outline=True, outline_width=(0.2, 0.05), vmin='p2',vmax='p98',wspace=.4)
In [13]:
#if you want vector sc.settings._vector_friendly = False
vector=False
n=20
pdDict = {}

if vector:
    sc.settings._vector_friendly = False
for pc in  [0,1]:
    TopPC_IDX = np.argpartition(adataBranch.varm["PCs"][:,pc], -n)[-n:]
    DownPC_IDX = np.argpartition(adataBranch.varm["PCs"][:,pc], n)[:n]
    pdDict[pc] = pd.DataFrame(adataBranch.varm["PCs"][:,pc][TopPC_IDX], index = adataBranch.var_names[TopPC_IDX], columns=["pc"+str(pc+1)])
    pdDict[pc] = pd.concat([pdDict[pc],pd.DataFrame(adataBranch.varm["PCs"][:,pc][DownPC_IDX], index = adataBranch.var_names[DownPC_IDX], columns=["pc"+str(pc+1)])])
    pdDict[pc]["gene"] = pdDict[pc].index.tolist()
    if pc == 0:
        pdDict[pc] = pdDict[pc].sort_values("pc"+str(pc+1))
    elif pc == 1:
        pdDict[pc] = pdDict[pc].sort_values("pc"+str(pc+1), ascending = False)
    
    
    

figsize = (6, 6)  #(width, height)
#Set axes
import matplotlib.pyplot as plt

fig, ax = plt.subplots(nrows=2, ncols=2, figsize=figsize,gridspec_kw={'width_ratios': [3, 1],'height_ratios': [3, 1]})

fig.tight_layout(pad=-2, h_pad=0)   #space between plots

ax1plot = sc.pl.pca(adataBranch, components=['1,2'], color=["leidenAnnotated"], 
                    ncols=1, add_outline=True, legend_loc="on data",size=100,legend_fontsize="small",
                    outline_width=(.1,.05), wspace=.2, show=False, ax=ax[0][0])



norm = TwoSlopeNorm(vmin=pdDict[0]["pc1"].min(), vcenter=0, vmax=pdDict[0]["pc1"].max())
colors = [plt.cm.RdYlGn(norm(c)) for c in pdDict[0]["pc1"]]
sns.barplot(data=pdDict[0], x="gene", y="pc1", color="pc1",palette=colors,ax=ax[1][0], zorder=3 ).tick_params(axis='x', rotation=90, labelsize=8)
ax[1][0].annotate("", xy=(.95,.99),xytext=(0.55, 0.99),
                  xycoords='axes fraction',
                  arrowprops=dict(arrowstyle="simple",facecolor="green"))
ax[1][0].annotate("", xy=(.05,.01),xytext=(0.45, 0.01),
                  xycoords='axes fraction',
                  arrowprops=dict(arrowstyle="simple",facecolor="red"))


norm = TwoSlopeNorm(vmin=pdDict[1]["pc2"].min(), vcenter=0, vmax=pdDict[1]["pc2"].max())
colors = [plt.cm.RdYlGn(norm(c)) for c in pdDict[1]["pc2"]]
sns.barplot(data=pdDict[1], x="pc2", y="gene", color="pc2",palette=colors,ax=ax[0][1], zorder=3 ).tick_params(axis='y',  
                                                                                                              labelsize=8, 
                                                                                                              labelright=True, labelleft=False,
                                                                                                              right=True, left=False)
ax[0][1].tick_params(axis='x', rotation=90)

ax[0][1].annotate("", xy=(.01,.95),xytext=(0.01, 0.55),
                  xycoords='axes fraction',
                  arrowprops=dict(arrowstyle="simple",facecolor="green"))
ax[0][1].annotate("", xy=(.99,.05),xytext=(0.99, 0.45),
                  xycoords='axes fraction',
                  arrowprops=dict(arrowstyle="simple",facecolor="red"))



ax[0][1].invert_xaxis()
ax[0][1].yaxis.set_label_position("right")
fig.delaxes(ax[1][1])

sc.settings._vector_friendly = True
In [14]:
pdDict = {}
for pc in  [0]:
    pdDict[pc] = pd.DataFrame(adataBranch.varm["PCs"][:,pc], index = adataBranch.var_names.tolist(), columns=["loading"])
    pdDict[pc]["gene"] = pdDict[pc].index.tolist()
    pdDict[pc] = pdDict[pc].sort_values("loading")
    pdDict[pc]["component"] = "pc"+str(pc+1)
    
TopLoadings = pdDict[pc]
TopLoadings
Out[14]:
loading gene component
HMGB2 -0.094620 HMGB2 pc1
NUSAP1 -0.088931 NUSAP1 pc1
CENPF -0.083994 CENPF pc1
TOP2A -0.083814 TOP2A pc1
PTTG1 -0.081935 PTTG1 pc1
... ... ... ...
CD24 0.080808 CD24 pc1
NSG1 0.084209 NSG1 pc1
GAP43 0.088641 GAP43 pc1
LHX1 0.089887 LHX1 pc1
STMN2 0.094153 STMN2 pc1

1804 rows × 3 columns

In [15]:
cellIDColorsMap = dict(zip(adataBranch.obs["cellID_newName"].cat.categories, adataBranch.uns["cellID_newName_colors"]))

Harmony PCs variance¶

In [16]:
adataBranch
adataBranch.obs["preservation"] = list(np.where(adataBranch.obs["dataset"] == "DownD100", "Fixed","Fresh"))
ColorDict = {}
for i in ["stage","type","cellID_newName","dataset",'leidenAnnotated']:
    ColorDict[i] = dict(zip(adataBranch.obs[i].cat.categories,adataBranch.uns["{}_colors".format(i)]))
ColorDict["preservation"] = {"Fresh":"#C4E4FF","Fixed":"#D6589F"}
PlotOrder = {"cellID_newName":['CTL01', 'CTL02A', 'CTL04E', 'CTL08A'],
             "stage":["early","mid","late"],
             "type":["upstream","downstream"],
             "preservation":["Fresh","Fixed"],
             "dataset":['UpD50','DownD50','UpD100_1', 'UpD100_2',  'DownD100','UpD300','DownD250'],
             "leidenAnnotated":['ProliferatingProgenitors', 'RadialGliaProgenitors', 'Neurons','intermediateProgenitors','MigratingNeurons']}
In [17]:
import matplotlib.pyplot as plt
from statsmodels.formula.api import ols
PCRegrDict = {}
npcs = 2
covToTest = ["cellID_newName","stage","type","preservation","dataset"]
sns.set_theme(style="ticks")
varianceSummary = pd.DataFrame()
for i in range(npcs):
	adataBranch.obsm["X_pca"]
	for n,c in enumerate(covToTest):
		Dummies = pd.get_dummies(adataBranch.obs[c])
		PCRegr = (Dummies.T * adataBranch.obsm["X_pca"][:,i].T).T.melt()
		PCRegr = PCRegr[PCRegr["value"] != 0]
		PCRegr["variable"] = PCRegr["variable"].astype("category")
		PCRegr["cov"] = c
		PCRegrDict["PC:{}_COV:{}".format(i+1,c)] = PCRegr.copy()
		sns.despine(offset=30)
		PCRegrModel = pd.get_dummies(PCRegrDict["PC:{}_COV:{}".format(i+1,c)], "variable").copy()
		formula = "".join(["value ~ "," + ".join(["C("+c+")" for c in PCRegrModel.columns[1:-1].tolist()])])
		fit = ols(formula, data=PCRegrModel).fit() 
		fit.rsquared_adj
		PCRegr["rsquared_adj"] = fit.rsquared_adj
		PCRegr["PC"] = i
		varianceSummary = pd.concat([varianceSummary,PCRegr ], ignore_index=True)

CovOrder = {i:varianceSummary.drop_duplicates(["PC","cov"])[varianceSummary.drop_duplicates(["PC","cov"])["PC"] == i].sort_values("rsquared_adj", ascending=False)["cov"].tolist() for i in varianceSummary["PC"].unique().tolist()}
for i in range(npcs):
	fig, axes = plt.subplots(1,len(covToTest), figsize=(30,5), dpi=300, sharex=False,sharey=False)
	plt.subplots_adjust(wspace=.5)
	adataBranch.obsm["X_pca"]
	for n,c in enumerate(CovOrder[i]):
		PCRegr = varianceSummary[(varianceSummary["PC"] == i) & (varianceSummary["cov"] == c)]
		sns.boxplot(data=PCRegr, x="variable", y="value", ax = axes[n],whis=[0, 100],palette=ColorDict[c], order=PlotOrder[c],hue_order=PlotOrder[c])
		sns.stripplot(data=PCRegr, x="variable", y="value", size=4, color=".3",ax = axes[n], order=PlotOrder[c],hue_order=PlotOrder[c])
		axes[n].title.set_text('Embeddings for component:{}, covariate:{}'.format(i+1,c))
		axes[n].set_xlabel(c, fontsize=20)
		axes[n].set_ylabel("PC{}".format(i+1), fontsize=20)
		sns.despine(offset=30)
		fit.rsquared_adj = PCRegr["rsquared_adj"].values[0]
		axes[n].text(0.5, 0, "rsquared_adj:{}".format(round(fit.rsquared_adj,2)), horizontalalignment='center', verticalalignment='center',transform=axes[n].transAxes)
		axes[n].tick_params(axis="x", rotation=45)
		plt.xticks(rotation=45)
		fig.autofmt_xdate(rotation=45)
<Figure size 432x288 with 0 Axes>

DPT¶

In [18]:
plt.rcdefaults()
with open("../data/resources/rcParams.yaml") as f:
    rcParamsDict = yaml.full_load(f)
    for k in rcParamsDict["rcParams"]:
        print("{} {}".format(k,rcParamsDict["rcParams"][k]))
        plt.rcParams[k] = rcParamsDict["rcParams"][k]
    for k1 in set(list(rcParamsDict)).difference(set(["rcParams"])):
        print("{} {}".format(k1,rcParamsDict[k1]))
figure.dpi 80
savefig.dpi 500
figure.figsize [10, 10]
axes.facecolor None
figure.facecolor None
dotSize 20
In [19]:
sc.tl.diffmap(adataBranch)


RootName = adataBranch.obs_names[adataBranch[:, ["TOP2A"]].X.argmax()]
root_idx = np.where(adataBranch.obs_names == RootName)[0][0]
adataBranch.uns['iroot'] = root_idx


sc.tl.dpt(adataBranch)
sc.pl.diffmap(adataBranch, color = ["dpt_pseudotime","TOP2A"],size = rcParamsDict["dotSize"],add_outline=True, outline_width=(0.2, 0.05), dimensions=(1,2),
              vmin='p2',vmax='p98', legend_fontsize="xx-large", frameon=False, wspace=.3, legend_loc="on data")
computing Diffusion Maps using n_comps=15(=n_dcs)
computing transitions
    finished (0:00:00)
    eigenvalues of transition matrix
    [1.         0.996359   0.98936844 0.9803072  0.9623219  0.96063995
     0.9543724  0.94208586 0.93551624 0.93360454 0.92206126 0.90515345
     0.9023301  0.8995216  0.8969439 ]
    finished: added
    'X_diffmap', diffmap coordinates (adata.obsm)
    'diffmap_evals', eigenvalues of transition matrix (adata.uns) (0:00:00)
computing Diffusion Pseudotime using n_dcs=10
    finished: added
    'dpt_pseudotime', the pseudotime (adata.obs) (0:00:00)
In [20]:
#adataBranch.write_h5ad(outdir+"/adatas/AdataLineage."+branchTag+".h5ad")

By timepoint (DPT)¶

In [21]:
cov = "stage"
In [22]:
timeCov="dpt_pseudotime"
In [23]:
sns.set_style("ticks")
In [24]:
#errors by dataset
fig, ax  = plt.subplots(1,1, figsize=(20,10))
for Stage in adataBranch.obs["stage"].unique(): 
    StageLT = adataBranch.obs[adataBranch.obs["stage"] == Stage]
    
    StageLT_smoothed = pd.DataFrame(index=np.linspace(0, 1, 10000))
    for dataset in StageLT["dataset"].unique():
        datasetLT = StageLT.loc[StageLT["dataset"] == dataset,timeCov]
        _bandwidth = round((datasetLT.max() - datasetLT.min()) * binWidthRate, 2)
        KernelData = datasetLT

        
        X = KernelData.values[:, np.newaxis]
        X_plot = np.linspace(0, 1, 10000)[:, np.newaxis]

        # Pick bandwidht
        kde_Calc = KernelDensity(kernel="gaussian", bandwidth=_bandwidth).fit(X)
        Y=np.exp(kde_Calc.score_samples(X_plot))
        
        StageLT_smoothed[dataset] = Y
        
    StageLT_smoothed["dpt_cut"] = StageLT_smoothed.index.tolist()
        
    # Calculate error and mean on smoothe values ()

    StageLT_smoothed["mean"] = StageLT_smoothed[[i for i in StageLT_smoothed.columns if i not in ['dpt_cut','stdev']]].mean(axis =1)
    StageLT_smoothed["stdev"] = StageLT_smoothed[[i for i in StageLT_smoothed.columns if i not in ['dpt_cut','stdev']]].std(axis =1)
    StageLT_smoothed["errMin"] = StageLT_smoothed["mean"] - StageLT_smoothed["stdev"]
    StageLT_smoothed["errMax"] = StageLT_smoothed["mean"] + StageLT_smoothed["stdev"]
    StageLT_smoothed["errMin"] = np.where(StageLT_smoothed["errMin"] < 0, 0, StageLT_smoothed["errMin"])
    
    plt.plot(StageLT_smoothed["dpt_cut"], StageLT_smoothed["mean"], '-', label =Stage,linewidth = 3,color = dict(zip(adataBranch.obs[cov].cat.categories.tolist(),adataBranch.uns["stage_colors"]))[Stage])
    plt.fill_between(StageLT_smoothed["dpt_cut"], StageLT_smoothed["errMin"], StageLT_smoothed["errMax"] , alpha=0.2,color = dict(zip(adataBranch.obs[cov].cat.categories.tolist(),adataBranch.uns["stage_colors"]))[Stage])
    plt.xlabel('pseudotime', size=30)
    plt.xticks(size=30)
    plt.yticks(size=30)

    plt.ylabel('Cells density', size=30)
    plt.legend(prop={'size': 30})
    plt.savefig(figDir+"/8_LineageFigures.dpt."+branchTag+".svg")
In [26]:
#errors by dataset
fig, ax  = plt.subplots(1,1, figsize=(20,10))

adataBranchCTL02 = adataBranch[adataBranch.obs["cellID_newName"] == "CTL02A"]
for Stage in adataBranchCTL02.obs["stage"].unique(): 
    StageLT = adataBranchCTL02.obs[adataBranchCTL02.obs["stage"] == Stage]
    
    StageLT_smoothed = pd.DataFrame(index=np.linspace(0, 1, 10000))
    for dataset in StageLT["dataset"].unique():
        datasetLT = StageLT.loc[StageLT["dataset"] == dataset,timeCov]
        _bandwidth = round((datasetLT.max() - datasetLT.min()) * binWidthRate, 2)
        KernelData = datasetLT
        
        
        X = KernelData.values[:, np.newaxis]
        X_plot = np.linspace(0, 1, 10000)[:, np.newaxis]

        # Pick bandwidht
        kde_Calc = KernelDensity(kernel="gaussian", bandwidth=_bandwidth).fit(X)
        Y=np.exp(kde_Calc.score_samples(X_plot))
        
        StageLT_smoothed[dataset] = Y
        
    StageLT_smoothed["dpt_cut"] = StageLT_smoothed.index.tolist()
        
    # Calculate error and mean on smoothe values ()

    StageLT_smoothed["mean"] = StageLT_smoothed[[i for i in StageLT_smoothed.columns if i not in ['dpt_cut','stdev']]].mean(axis =1)
    StageLT_smoothed["stdev"] = StageLT_smoothed[[i for i in StageLT_smoothed.columns if i not in ['dpt_cut','stdev']]].std(axis =1)
    StageLT_smoothed["errMin"] = StageLT_smoothed["mean"] - StageLT_smoothed["stdev"]
    StageLT_smoothed["errMax"] = StageLT_smoothed["mean"] + StageLT_smoothed["stdev"]
    StageLT_smoothed["errMin"] = np.where(StageLT_smoothed["errMin"] < 0, 0, StageLT_smoothed["errMin"])
    
    plt.plot(StageLT_smoothed["dpt_cut"], StageLT_smoothed["mean"], '-', label =Stage,linewidth = 3,color = dict(zip(adataBranchCTL02.obs[cov].cat.categories.tolist(),adataBranchCTL02.uns["stage_colors"]))[Stage])
    plt.fill_between(StageLT_smoothed["dpt_cut"], StageLT_smoothed["errMin"], StageLT_smoothed["errMax"] , alpha=0.2,color = dict(zip(adataBranchCTL02.obs[cov].cat.categories.tolist(),adataBranchCTL02.uns["stage_colors"]))[Stage])
    plt.xlabel('pseudotime', size=30)
    plt.xticks(size=30)
    plt.yticks(size=30)

    plt.ylabel('Cells density', size=30)
    plt.legend(prop={'size': 30})
    plt.savefig(figDir+"/8_LineageFigures.dpt.CTL02A."+branchTag+".svg")

By paradigm (DPT)¶

In [25]:
cov = "type"
In [26]:
#with errors by dataset
fig, ax  = plt.subplots(1,1, figsize=(20,10))
for Stage in adataBranch.obs["type"].unique(): 
    StageLT = adataBranch.obs[adataBranch.obs["type"] == Stage]
    
    StageLT_smoothed = pd.DataFrame(index=np.linspace(0, 1, 10000))
    for dataset in StageLT["dataset"].unique():
        datasetLT = StageLT.loc[StageLT["dataset"] == dataset,timeCov]
        _bandwidth = round((datasetLT.max() - datasetLT.min()) * binWidthRate, 2)

        KernelData = datasetLT

        
        X = KernelData.values[:, np.newaxis]
        X_plot = np.linspace(0, 1, 10000)[:, np.newaxis]

        # Pick bandwidht
        kde_Calc = KernelDensity(kernel="gaussian", bandwidth=_bandwidth).fit(X)
        Y=np.exp(kde_Calc.score_samples(X_plot))
        
        StageLT_smoothed[dataset] = Y
        
    StageLT_smoothed["dpt_cut"] = StageLT_smoothed.index.tolist()
        
    # Calculate error and mean on smoothe values ()

    StageLT_smoothed["mean"] = StageLT_smoothed[[i for i in StageLT_smoothed.columns if i not in ['dpt_cut','stdev']]].mean(axis =1)
    StageLT_smoothed["stdev"] = StageLT_smoothed[[i for i in StageLT_smoothed.columns if i not in ['dpt_cut','stdev']]].std(axis =1)
    StageLT_smoothed["errMin"] = StageLT_smoothed["mean"] - StageLT_smoothed["stdev"]
    StageLT_smoothed["errMax"] = StageLT_smoothed["mean"] + StageLT_smoothed["stdev"]
    StageLT_smoothed["errMin"] = np.where(StageLT_smoothed["errMin"] < 0, 0, StageLT_smoothed["errMin"])
    
    plt.plot(StageLT_smoothed["dpt_cut"], StageLT_smoothed["mean"], '-', label =Stage,linewidth = 3,color = dict(zip(adataBranch.obs[cov].cat.categories.tolist(),adataBranch.uns["type_colors"]))[Stage])
    plt.fill_between(StageLT_smoothed["dpt_cut"], StageLT_smoothed["errMin"], StageLT_smoothed["errMax"] , alpha=0.2,color = dict(zip(adataBranch.obs[cov].cat.categories.tolist(),adataBranch.uns["type_colors"]))[Stage])

    plt.xlabel('pseudotime', size=30)
    plt.xticks(size=30)
    plt.yticks(size=30)

    plt.ylabel('Cells density', size=30)
    plt.legend(prop={'size': 30})
    plt.savefig(figDir+"/8_LineageFigures.Up_vs_Down.dpt."+branchTag+".svg")

Explore Genotypes¶

In [27]:
#######---original adata ------- Load Original adata and plot uncorrected PCA and original compositions

sc.settings.verbosity = 0 


adataInitPCA = adataBranch.copy()


compositions = pd.DataFrame(adataInitPCA.obs.groupby(["stage","cellID_newName"]).size())
compositions = compositions.reset_index().rename(columns={0:"number_of_cells"})
fig = px.bar(compositions, x="stage", y="number_of_cells", color="cellID_newName", 
             category_orders={"stage":["early","mid","late"]}, height=800,width=1000, template="plotly_white",
             color_discrete_map = dict(zip(adataInitPCA.obs["cellID_newName"].cat.categories, adataInitPCA.uns["cellID_newName_colors"])))

fig.update_traces(marker_line_color='rgb(8,48,107)',
                  marker_line_width=1.5, opacity=1)

fig.show()

Downsampling loops (DPT)¶

In [28]:
ReproducibilityDF = pd.DataFrame() 
ReproducibilityRaw = pd.DataFrame() 
adataInitPCA = adataBranch.copy()

adataInitPCA = adataInitPCA[adataInitPCA.obs["stage"].isin(MultiTPTstages)]
#Remove genotypes not in all timepoints
GoodIDs = pd.crosstab(adataInitPCA.obs.cellID_newName,adataInitPCA.obs.stage ) > min_cells
GoodIDs = GoodIDs[GoodIDs.sum(axis =1) == len(adataInitPCA.obs["stage"].unique())].index.tolist()
adataInitPCA = adataInitPCA[adataInitPCA.obs.cellID_newName.isin(GoodIDs)]
    
compositions = pd.DataFrame(adataInitPCA.obs.groupby(["stage","cellID_newName"]).size())
compositions = compositions.reset_index().rename(columns={0:"number_of_cells"})
fig = px.bar(compositions, x="stage", y="number_of_cells", color="cellID_newName", title="Balance Before each loop",
             category_orders={"stage":["early","mid","late"]}, height=800,width=1000, template="plotly_white",
             color_discrete_map = dict(zip(adataInitPCA.obs["cellID_newName"].cat.categories, adataInitPCA.uns["cellID_newName_colors"])))

fig.update_traces(marker_line_color='rgb(8,48,107)',
                  marker_line_width=1.5, opacity=1)

fig.show()

    
for seed in range(ResamplingIterations):
    random.seed(seed)
    
    adataGenotypes = adataInitPCA.copy()


    #Subset timepoint if needed
    MinCells = pd.crosstab(adataGenotypes.obs.cellID_newName,adataGenotypes.obs.stage ) 
    MinCells = MinCells.min().to_dict()

    sampledBCs = []
    for stage in adataGenotypes.obs.stage.unique():
        samplingSize = MinCells[stage]
        sampledBCsStage = [ random.sample(adataGenotypes[(adataGenotypes.obs["stage"] == stage) & (adataGenotypes.obs["cellID_newName"] == ID)].obs_names.tolist() ,samplingSize) for ID in adataGenotypes.obs["cellID_newName"].unique().tolist()  ]
        sampledBCsStage = [item for sublist in sampledBCsStage for item in sublist]
        sampledBCs = sampledBCs + sampledBCsStage

    adataGenotypes = adataGenotypes[sampledBCs]
    
    #Trim extreme values
#     trimExtremes = [0.01,.99]
#     minDPT, maxDPT = np.quantile(adataGenotypes.obs["pc1"], trimExtremes)
#     adataGenotypes = adataGenotypes[(adataGenotypes.obs["pc1"] > minDPT) & (adataGenotypes.obs["pc1"] < maxDPT)]
    
    _bandwidth = round((adataGenotypes.obs["dpt_pseudotime"].max() - adataGenotypes.obs["dpt_pseudotime"].min()) * binWidthRate, 2)
    seedPseudotime = pd.DataFrame()
    seedPseudotimeRaw = pd.DataFrame()

    for cellID in adataGenotypes.obs["cellID_newName"].unique(): 
        LocalPseudotime = pd.DataFrame()
        LocalPseudotimeRaw = pd.DataFrame()
        KernelData = adataGenotypes.obs.loc[adataBranch.obs["cellID_newName"] == cellID, "dpt_pseudotime"]
        X = KernelData.values[:, np.newaxis]
        X_plot = np.linspace(adataGenotypes.obs["dpt_pseudotime"].min(), adataGenotypes.obs["dpt_pseudotime"].max(), 10000)[:, np.newaxis]
        # Pick bandwidht
        kde_Calc = KernelDensity(kernel="gaussian", bandwidth=_bandwidth).fit(X)
        Y=np.exp(kde_Calc.score_samples(X_plot))
        LocalPseudotime[seed] = Y
        LocalPseudotime["cellID"] = cellID
        LocalPseudotime["x"] = X_plot.flatten()
        seedPseudotime = pd.concat([seedPseudotime,LocalPseudotime ], ignore_index=True, axis = 0)
        #Raw values non smoothed
        LocalPseudotimeRaw[seed] = KernelData.tolist()
        LocalPseudotimeRaw["cellID"] = cellID
        seedPseudotimeRaw = pd.concat([seedPseudotimeRaw,LocalPseudotimeRaw], ignore_index=True)
    if "cellID" in ReproducibilityDF.columns:
        ReproducibilityDF = pd.concat([seedPseudotime[seed], ReproducibilityDF], axis = 1)
        ReproducibilityRaw = pd.concat([seedPseudotimeRaw[seed], ReproducibilityRaw], axis = 1)
    else:
        ReproducibilityDF = pd.concat([ReproducibilityDF, seedPseudotime], axis =1 )
        ReproducibilityRaw = pd.concat([ReproducibilityRaw, seedPseudotimeRaw], axis =1 )
 
        
        
compositions = pd.DataFrame(adataGenotypes.obs.groupby(["stage","cellID_newName"]).size())
compositions = compositions.reset_index().rename(columns={0:"number_of_cells"})
fig = px.bar(compositions, x="stage", y="number_of_cells", color="cellID_newName", title="Balance Operated whithin each loop",
             category_orders={"stage":["early","mid","late"]}, height=800,width=1000, template="plotly_white",
             color_discrete_map = dict(zip(adataGenotypes.obs["cellID_newName"].cat.categories, adataGenotypes.uns["cellID_newName_colors"])))

fig.update_traces(marker_line_color='rgb(8,48,107)',
                  marker_line_width=1.5, opacity=1)

fig.show()


plotDF = ReproducibilityDF.copy()

plotDF["std"] = plotDF[[c for c in plotDF.columns if c not in ["x","cellID","std","mean",'max','min']]].std(axis =1)

plotDF["mean"] = plotDF[[c for c in plotDF.columns if c not in ["x","cellID","std","mean",'max','min']]].mean(axis =1)
plotDF["max"] = plotDF["mean"]+plotDF["std"]
plotDF["min"] = plotDF["mean"]-plotDF["std"]


fig, ax  = plt.subplots(1,1, figsize=(20,10))
for g in plotDF.cellID.unique():
    plotDFID = plotDF[plotDF.cellID == g]
    plt.plot(plotDFID["x"], plotDFID["mean"], '-',
             label =g,
             color = dict(zip(adataGenotypes.obs["cellID_newName"].cat.categories.tolist(),adataGenotypes.uns["cellID_newName_colors"]))[g],
             linewidth = 3)
    plt.fill_between(plotDFID["x"], plotDFID["min"], plotDFID["max"] , 
                     alpha=0.2,
                     color = dict(zip(adataGenotypes.obs["cellID_newName"].cat.categories.tolist(),adataGenotypes.uns["cellID_newName_colors"]))[g])

plt.xlabel('pseudotime', size=30)
plt.xticks(size=30)
plt.yticks(size=30)
plt.legend(prop={'size': 30})
plt.savefig(figDir+"/8_LineageFigures.Genotypes."+branchTag+".svg")
In [29]:
DPTdf = plotDF.rename(columns=dict(zip([c for c in plotDF.columns if isinstance(c, int)], ["iteration."+str(c) for c in plotDF.columns if isinstance(c, int)]))).rename(columns={"x":"pseudotime_bin"})
DPTdf["Branch"] = branchTag
DPTdf.to_csv(outdir+"/PseudotimeGenotypeDensity."+branchTag+".tsv", index=False, sep="\t")

Next we assess if the difference among genotype groups is preserved when:

  1. After each random sampling pre-processing and integration are repeated
  2. We take as pseudotime measure PC1 vlues instead of diffusion pseudotime
In [30]:
ReproducibilityDF = pd.DataFrame() 
ReproducibilityRaw = pd.DataFrame() 

adataInitPCA = adataBranch.copy()
adataInitPCA = adataInitPCA[adataInitPCA.obs["stage"].isin(MultiTPTstages)]
#Remove genotypes not in all timepoints
GoodIDs = pd.crosstab(adataInitPCA.obs.cellID_newName,adataInitPCA.obs.stage ) > min_cells
GoodIDs = GoodIDs[GoodIDs.sum(axis =1) == len(adataInitPCA.obs["stage"].unique())].index.tolist()
adataInitPCA = adataInitPCA[adataInitPCA.obs.cellID_newName.isin(GoodIDs)]
    
compositions = pd.DataFrame(adataInitPCA.obs.groupby(["stage","cellID_newName"]).size())
compositions = compositions.reset_index().rename(columns={0:"number_of_cells"})
fig = px.bar(compositions, x="stage", y="number_of_cells", color="cellID_newName", title="Balance Before each loop",
             category_orders={"stage":["early","mid","late"]}, height=800,width=1000, template="plotly_white",
             color_discrete_map = dict(zip(adataInitPCA.obs["cellID_newName"].cat.categories, adataInitPCA.uns["cellID_newName_colors"])))

fig.update_traces(marker_line_color='rgb(8,48,107)',
                  marker_line_width=1.5, opacity=1)

fig.show()


for seed in range(ResamplingIterations):
    #random.seed(seed)
    
    adataGenotypes = adataInitPCA.copy()
    
    #Downsample genotypes
    MinCells = pd.crosstab(adataGenotypes.obs.cellID_newName,adataGenotypes.obs.stage ) 
    MinCells = MinCells.min().to_dict()

    sampledBCs = []
    for stage in adataGenotypes.obs.stage.unique():
        samplingSize = MinCells[stage]
        sampledBCsStage = [ random.sample(adataGenotypes[(adataGenotypes.obs["stage"] == stage) & (adataGenotypes.obs["cellID_newName"] == ID)].obs_names.tolist() ,samplingSize) for ID in adataGenotypes.obs["cellID_newName"].unique().tolist()  ]
        sampledBCsStage = [item for sublist in sampledBCsStage for item in sublist]
        sampledBCs = sampledBCs + sampledBCsStage
    adataGenotypes = adataGenotypes[sampledBCs]
    
    # Retrieved unscaled counts
    adataGenotypes.X = adataGenotypes.layers["unscaled"].todense()
    adataGenotypes = PurgeAdata(adataGenotypes)
    
    sc.pp.normalize_total(adataGenotypes, target_sum=1e4)
    sc.pp.log1p(adataGenotypes)
    adataGenotypes.var["highly_variable"] = True
    sc.pp.highly_variable_genes(adataBranch, min_mean=0.0125, max_mean=5, min_disp=0.5, batch_key = "dataset")
    sc.pp.regress_out(adataGenotypes, ['total_counts','pct_counts_mt'], n_jobs=4)
    sc.pp.scale(adataGenotypes, zero_center=False)
    sc.tl.pca(adataGenotypes, svd_solver='arpack', use_highly_variable=True)
    sce.pp.harmony_integrate(adataGenotypes, 'dataset', max_iter_harmony=20,adjusted_basis="X_pca",random_state = 0, theta = harmonyTheta, lamb = 2)

    adataGenotypes.obs["X_pca.0"] = adataGenotypes.obsm["X_pca"][:,0]

    
    _bandwidth = round((adataGenotypes.obs["X_pca.0"].max() - adataGenotypes.obs["X_pca.0"].min()) * binWidthRate, 2)
    seedPseudotime = pd.DataFrame()
    seedPseudotimeRaw = pd.DataFrame()

    for cellID in adataGenotypes.obs["cellID_newName"].unique(): 
        LocalPseudotime = pd.DataFrame()
        LocalPseudotimeRaw = pd.DataFrame()
        KernelData = adataGenotypes.obs.loc[adataBranch.obs["cellID_newName"] == cellID, "X_pca.0"]
        X = KernelData.values[:, np.newaxis]
        X_plot = np.linspace(adataGenotypes.obs["X_pca.0"].min(), adataGenotypes.obs["X_pca.0"].max(), 10000)[:, np.newaxis]
        # Pick bandwidht
        kde_Calc = KernelDensity(kernel="gaussian", bandwidth=_bandwidth).fit(X)
        Y=np.exp(kde_Calc.score_samples(X_plot))
        LocalPseudotime[seed] = Y
        LocalPseudotime["cellID"] = cellID
        LocalPseudotime["x"] = X_plot.flatten()
        seedPseudotime = pd.concat([seedPseudotime,LocalPseudotime ], ignore_index=True, axis = 0)
        #Raw values non smoothed
        LocalPseudotimeRaw[seed] = KernelData.tolist()
        LocalPseudotimeRaw["cellID"] = cellID
        seedPseudotimeRaw = pd.concat([seedPseudotimeRaw,LocalPseudotimeRaw], ignore_index=True)
    if "cellID" in ReproducibilityDF.columns:
        ReproducibilityDF = pd.concat([seedPseudotime[seed], ReproducibilityDF], axis = 1)
        ReproducibilityRaw = pd.concat([seedPseudotimeRaw[seed], ReproducibilityRaw], axis = 1)
    else:
        ReproducibilityDF = pd.concat([ReproducibilityDF, seedPseudotime], axis =1 )
        ReproducibilityRaw = pd.concat([ReproducibilityRaw, seedPseudotimeRaw], axis =1 )
 
        
        
compositions = pd.DataFrame(adataGenotypes.obs.groupby(["stage","cellID_newName"]).size())
compositions = compositions.reset_index().rename(columns={0:"number_of_cells"})
fig = px.bar(compositions, x="stage", y="number_of_cells", color="cellID_newName", title="Balance Operated whithin each loop",
             category_orders={"stage":["early","mid","late"]}, height=800,width=1000, template="plotly_white",
             color_discrete_map = dict(zip(adataGenotypes.obs["cellID_newName"].cat.categories, adataGenotypes.uns["cellID_newName_colors"])))

fig.update_traces(marker_line_color='rgb(8,48,107)',
                  marker_line_width=1.5, opacity=1)

fig.show()



plotDF = ReproducibilityDF.copy()

plotDF["std"] = plotDF[[c for c in plotDF.columns if c not in ["x","cellID","std","mean",'max','min']]].std(axis =1)

plotDF["mean"] = plotDF[[c for c in plotDF.columns if c not in ["x","cellID","std","mean",'max','min']]].mean(axis =1)
plotDF["max"] = plotDF["mean"]+plotDF["std"]
plotDF["min"] = plotDF["mean"]-plotDF["std"]


fig, ax  = plt.subplots(1,1, figsize=(20,10))
sns.set_style("ticks")
for g in plotDF.cellID.unique():
    plotDFID = plotDF[plotDF.cellID == g]
    plt.plot(plotDFID["x"], plotDFID["mean"], '-',
             label =g,
             color = dict(zip(adataGenotypes.obs["cellID_newName"].cat.categories.tolist(),adataGenotypes.uns["cellID_newName_colors"]))[g],
             linewidth = 3)
    plt.fill_between(plotDFID["x"], plotDFID["min"], plotDFID["max"] , 
                     alpha=0.2,
                     color = dict(zip(adataGenotypes.obs["cellID_newName"].cat.categories.tolist(),adataGenotypes.uns["cellID_newName_colors"]))[g])

plt.xlabel('PC1', size=30)
plt.xticks(size=30)
plt.yticks(size=30)
plt.legend(prop={'size': 30})
plt.savefig(figDir+"/8_LineageFigures.Genotypes."+branchTag+"PC1.svg")
2024-05-29 06:48:55,050 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:48:55,249 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:48:55,449 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:48:55,586 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:48:55,715 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:48:55,817 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:48:55,944 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:48:56,064 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:48:56,151 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:48:56,227 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:48:56,295 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:48:56,372 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:48:56,440 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:48:56,510 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:48:56,586 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:48:56,654 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:48:56,722 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:48:56,790 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:48:56,858 - harmonypy - INFO - Converged after 18 iterations
2024-05-29 06:49:05,259 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:49:05,453 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:49:05,645 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:49:05,804 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:49:05,914 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:49:06,039 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:49:06,134 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:49:06,249 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:49:06,330 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:49:06,396 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:49:06,463 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:49:06,529 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:49:06,604 - harmonypy - INFO - Converged after 12 iterations
2024-05-29 06:49:14,850 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:49:15,044 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:49:15,238 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:49:15,436 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:49:15,546 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:49:15,638 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:49:15,748 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:49:15,832 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:49:15,908 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:49:15,985 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:49:16,062 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:49:16,139 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:49:16,208 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:49:16,276 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:49:16,343 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:49:16,420 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:49:16,488 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:49:16,557 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:49:16,624 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:49:16,700 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:49:16,768 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:49:25,014 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:49:25,210 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:49:25,402 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:49:25,586 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:49:25,711 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:49:25,811 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:49:25,895 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:49:25,987 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:49:26,117 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:49:26,204 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:49:26,289 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:49:26,367 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:49:26,436 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:49:26,515 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:49:26,583 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:49:26,669 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:49:26,754 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:49:26,839 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:49:26,916 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:49:27,001 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:49:27,079 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:49:35,058 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:49:35,256 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:49:35,456 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:49:35,620 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:49:35,765 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:49:35,908 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:49:36,011 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:49:36,089 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:49:36,158 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:49:36,230 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:49:36,300 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:49:36,368 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:49:36,437 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:49:36,505 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:49:36,574 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:49:36,651 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:49:36,721 - harmonypy - INFO - Converged after 16 iterations
2024-05-29 06:49:44,793 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:49:44,990 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:49:45,184 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:49:45,296 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:49:45,449 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:49:45,551 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:49:45,646 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:49:45,781 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:49:45,856 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:49:45,928 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:49:46,004 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:49:46,071 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:49:46,138 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:49:46,209 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:49:46,287 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:49:46,357 - harmonypy - INFO - Converged after 15 iterations
2024-05-29 06:49:54,384 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:49:54,583 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:49:54,778 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:49:54,971 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:49:55,100 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:49:55,194 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:49:55,296 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:49:55,449 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:49:55,527 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:49:55,597 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:49:55,676 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:49:55,752 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:49:55,822 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:49:55,895 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:49:55,972 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:49:56,048 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:49:56,117 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:49:56,193 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:49:56,278 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:49:56,347 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:49:56,425 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:50:04,417 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:50:04,613 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:50:04,804 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:50:05,005 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:50:05,149 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:50:05,293 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:50:05,396 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:50:05,540 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:50:05,627 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:50:05,697 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:50:05,783 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:50:05,860 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:50:05,963 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:50:06,044 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:50:06,121 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:50:06,199 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:50:06,268 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:50:06,337 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:50:06,406 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:50:06,476 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:50:06,547 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:50:14,663 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:50:14,859 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:50:15,053 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:50:15,246 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:50:15,397 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:50:15,499 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:50:15,601 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:50:15,678 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:50:15,780 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:50:15,862 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:50:15,955 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:50:16,024 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:50:16,108 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:50:16,176 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:50:16,253 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:50:16,330 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:50:16,407 - harmonypy - INFO - Converged after 16 iterations
2024-05-29 06:50:24,440 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:50:24,633 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:50:24,827 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:50:25,018 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:50:25,129 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:50:25,214 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:50:25,306 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:50:25,424 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:50:25,508 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:50:25,592 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:50:25,660 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:50:25,736 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:50:25,813 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:50:25,890 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:50:25,967 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:50:26,034 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:50:26,102 - harmonypy - INFO - Converged after 16 iterations
2024-05-29 06:50:34,129 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:50:34,320 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:50:34,513 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:50:34,680 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:50:34,875 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:50:34,967 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:50:35,069 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:50:35,156 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:50:35,256 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:50:35,341 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:50:35,418 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:50:35,487 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:50:35,562 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:50:35,630 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:50:35,699 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:50:35,768 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:50:35,841 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:50:35,909 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:50:35,976 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:50:36,044 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:50:36,113 - harmonypy - INFO - Converged after 20 iterations
2024-05-29 06:50:44,501 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:50:44,695 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:50:44,890 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:50:45,081 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:50:45,271 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:50:45,371 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:50:45,492 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:50:45,568 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:50:45,645 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:50:45,713 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:50:45,790 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:50:45,860 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:50:45,936 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:50:46,004 - harmonypy - INFO - Converged after 13 iterations
2024-05-29 06:50:54,085 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:50:54,288 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:50:54,489 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:50:54,691 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:50:54,848 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:50:54,962 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:50:55,059 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:50:55,162 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:50:55,310 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:50:55,511 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:50:55,597 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:50:55,666 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:50:55,733 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:50:55,801 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:50:55,882 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:50:55,956 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:50:56,023 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:50:56,092 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:50:56,162 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:50:56,230 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:50:56,297 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:51:04,358 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:51:04,554 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:51:04,746 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:51:04,889 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:51:05,000 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:51:05,105 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:51:05,210 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:51:05,319 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:51:05,413 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:51:05,481 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:51:05,568 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:51:05,641 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:51:05,711 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:51:05,781 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:51:05,852 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:51:05,922 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:51:05,991 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:51:06,061 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:51:06,133 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:51:06,204 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:51:06,273 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:51:14,588 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:51:14,780 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:51:14,970 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:51:15,167 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:51:15,296 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:51:15,423 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:51:15,548 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:51:15,632 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:51:15,716 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:51:15,798 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:51:15,877 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:51:15,952 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:51:16,018 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:51:16,085 - harmonypy - INFO - Converged after 13 iterations
2024-05-29 06:51:24,404 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:51:24,599 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:51:24,792 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:51:24,935 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:51:25,046 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:51:25,140 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:51:25,253 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:51:25,355 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:51:25,441 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:51:25,519 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:51:25,596 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:51:25,665 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:51:25,734 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:51:25,803 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:51:25,873 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:51:25,951 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:51:26,022 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:51:26,093 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:51:26,165 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:51:26,235 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:51:26,305 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:51:34,732 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:51:34,932 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:51:35,130 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:51:35,331 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:51:35,483 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:51:35,623 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:51:35,747 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:51:35,851 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:51:35,940 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:51:36,047 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:51:36,154 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:51:36,226 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:51:36,300 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:51:36,373 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:51:36,447 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:51:36,522 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:51:36,595 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:51:36,670 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:51:36,743 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:51:36,817 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:51:36,890 - harmonypy - INFO - Converged after 20 iterations
2024-05-29 06:51:45,423 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:51:45,622 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:51:45,821 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:51:46,017 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:51:46,160 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:51:46,328 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:51:46,449 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:51:46,554 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:51:46,649 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:51:46,752 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:51:46,860 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:51:46,966 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:51:47,063 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:51:47,170 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:51:47,260 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:51:47,349 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:51:47,437 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:51:47,518 - harmonypy - INFO - Converged after 17 iterations
2024-05-29 06:51:55,779 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:51:55,986 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:51:56,183 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:51:56,379 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:51:56,484 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:51:56,596 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:51:56,691 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:51:56,777 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:51:56,862 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:51:56,950 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:51:57,019 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:51:57,089 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:51:57,159 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:51:57,228 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:51:57,298 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:51:57,368 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:51:57,437 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:51:57,506 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:51:57,582 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:51:57,650 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:51:57,726 - harmonypy - INFO - Converged after 20 iterations
2024-05-29 06:52:05,952 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:52:06,146 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:52:06,338 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:52:06,466 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:52:06,568 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:52:06,751 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:52:06,862 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:52:06,972 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:52:07,058 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:52:07,135 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:52:07,223 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:52:07,292 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:52:07,360 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:52:07,438 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:52:07,531 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:52:07,600 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:52:07,669 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:52:07,738 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:52:07,815 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:52:07,883 - harmonypy - INFO - Converged after 19 iterations
2024-05-29 06:52:16,417 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:52:16,619 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:52:16,814 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:52:16,933 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:52:17,087 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:52:17,199 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:52:17,294 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:52:17,405 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:52:17,493 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:52:17,581 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:52:17,652 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:52:17,729 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:52:17,799 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:52:17,877 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:52:17,947 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:52:18,024 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:52:18,093 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:52:18,171 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:52:18,249 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:52:18,328 - harmonypy - INFO - Converged after 19 iterations
2024-05-29 06:52:26,755 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:52:26,984 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:52:27,242 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:52:27,485 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:52:27,606 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:52:27,709 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:52:27,838 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:52:27,917 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:52:27,994 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:52:28,080 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:52:28,150 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:52:28,227 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:52:28,295 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:52:28,362 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:52:28,430 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:52:28,506 - harmonypy - INFO - Converged after 15 iterations
2024-05-29 06:52:36,562 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:52:36,760 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:52:36,955 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:52:37,101 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:52:37,247 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:52:37,359 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:52:37,487 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:52:37,574 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:52:37,659 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:52:37,741 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:52:37,811 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:52:37,880 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:52:37,950 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:52:38,019 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:52:38,090 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:52:38,159 - harmonypy - INFO - Converged after 15 iterations
2024-05-29 06:52:46,283 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:52:46,486 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:52:46,687 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:52:46,835 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:52:46,957 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:52:47,096 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:52:47,199 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:52:47,336 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:52:47,430 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:52:47,517 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:52:47,603 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:52:47,680 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:52:47,748 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:52:47,817 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:52:47,886 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:52:47,963 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:52:48,041 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:52:48,109 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:52:48,204 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:52:48,290 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:52:48,394 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:52:57,128 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:52:57,324 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:52:57,518 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:52:57,706 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:52:57,825 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:52:57,953 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:52:58,038 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:52:58,123 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:52:58,192 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:52:58,269 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:52:58,420 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:52:58,499 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:52:58,567 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:52:58,640 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:52:58,709 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:52:58,777 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:52:58,846 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:52:58,914 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:52:58,982 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:52:59,060 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:52:59,129 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:53:07,144 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:53:07,342 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:53:07,534 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:53:07,678 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:53:07,799 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:53:07,935 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:53:08,090 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:53:08,234 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:53:08,330 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:53:08,415 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:53:08,509 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:53:08,586 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:53:08,655 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:53:08,768 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:53:08,845 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:53:08,913 - harmonypy - INFO - Converged after 15 iterations
2024-05-29 06:53:17,012 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:53:17,219 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:53:17,402 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:53:17,537 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:53:17,662 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:53:17,760 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:53:17,843 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:53:17,943 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:53:18,025 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:53:18,100 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:53:18,184 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:53:18,268 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:53:18,342 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:53:18,425 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:53:18,491 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:53:18,574 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:53:18,640 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:53:18,713 - harmonypy - INFO - Converged after 17 iterations
2024-05-29 06:53:27,464 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:53:27,660 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:53:27,853 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:53:28,028 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:53:28,163 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:53:28,346 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:53:28,447 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:53:28,557 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:53:28,653 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:53:28,730 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:53:28,798 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:53:28,883 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:53:28,951 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:53:29,019 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:53:29,087 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:53:29,153 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:53:29,219 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:53:29,286 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:53:29,352 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:53:29,418 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:53:29,490 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:53:37,455 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:53:37,650 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:53:37,842 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:53:37,977 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:53:38,070 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:53:38,195 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:53:38,271 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:53:38,347 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:53:38,424 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:53:38,491 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:53:38,568 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:53:38,636 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:53:38,713 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:53:38,814 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:53:38,923 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:53:38,992 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:53:39,058 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:53:39,125 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:53:39,192 - harmonypy - INFO - Converged after 18 iterations
2024-05-29 06:53:47,362 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:53:47,559 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:53:47,750 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:53:47,942 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:53:48,060 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:53:48,187 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:53:48,297 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:53:48,398 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:53:48,490 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:53:48,575 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:53:48,643 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:53:48,712 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:53:48,780 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:53:48,848 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:53:48,917 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:53:48,986 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:53:49,055 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:53:49,124 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:53:49,192 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:53:49,261 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:53:49,331 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:53:57,306 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:53:57,500 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:53:57,693 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:53:57,850 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:53:57,969 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:53:58,062 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:53:58,154 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:53:58,232 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:53:58,374 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:53:58,565 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:53:58,633 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:53:58,700 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:53:58,769 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:53:58,837 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:53:58,904 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:53:58,973 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:53:59,041 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:53:59,109 - harmonypy - INFO - Converged after 17 iterations
2024-05-29 06:54:07,228 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:54:07,422 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:54:07,612 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:54:07,752 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:54:07,900 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:54:08,031 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:54:08,122 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:54:08,206 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:54:08,280 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:54:08,347 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:54:08,420 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:54:08,504 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:54:08,602 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:54:08,713 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:54:08,854 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:54:09,029 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:54:09,297 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:54:09,533 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:54:09,692 - harmonypy - INFO - Converged after 18 iterations
2024-05-29 06:54:17,949 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:54:18,144 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:54:18,342 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:54:18,534 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:54:18,653 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:54:18,805 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:54:18,931 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:54:19,014 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:54:19,097 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:54:19,164 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:54:19,252 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:54:19,329 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:54:19,405 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:54:19,473 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:54:19,542 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:54:19,610 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:54:19,678 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:54:19,746 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:54:19,815 - harmonypy - INFO - Converged after 18 iterations
2024-05-29 06:54:27,917 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:54:28,111 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:54:28,294 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:54:28,444 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:54:28,594 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:54:28,727 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:54:28,810 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:54:28,892 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:54:28,966 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:54:29,040 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:54:29,107 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:54:29,173 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:54:29,240 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:54:29,307 - harmonypy - INFO - Converged after 13 iterations
2024-05-29 06:54:37,347 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:54:37,540 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:54:37,731 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:54:37,848 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:54:37,964 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:54:38,080 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:54:38,188 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:54:38,288 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:54:38,380 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:54:38,464 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:54:38,548 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:54:38,633 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:54:38,717 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:54:38,800 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:54:38,876 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:54:38,976 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:54:39,060 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:54:39,144 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:54:39,219 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:54:39,303 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:54:39,386 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:54:47,458 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:54:47,653 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:54:47,841 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:54:48,015 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:54:48,155 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:54:48,296 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:54:48,380 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:54:48,463 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:54:48,580 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:54:48,672 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:54:48,748 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:54:48,814 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:54:48,881 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:54:48,948 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:54:49,018 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:54:49,102 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:54:49,169 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:54:49,236 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:54:49,311 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:54:49,379 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:54:49,454 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:54:57,694 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:54:57,892 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:54:58,056 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:54:58,253 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:54:58,391 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:54:58,478 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:54:58,590 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:54:58,677 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:54:58,755 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:54:58,833 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:54:58,912 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:54:58,983 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:54:59,060 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:54:59,129 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:54:59,199 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:54:59,289 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:54:59,359 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:54:59,436 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:54:59,514 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:54:59,592 - harmonypy - INFO - Converged after 19 iterations
2024-05-29 06:55:07,571 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:55:07,769 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:55:07,966 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:55:08,161 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:55:08,330 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:55:08,436 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:55:08,523 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:55:08,601 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:55:08,679 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:55:08,757 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:55:08,826 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:55:08,896 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:55:08,966 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:55:09,037 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:55:09,106 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:55:09,175 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:55:09,246 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:55:09,317 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:55:09,386 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:55:09,456 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:55:09,525 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:55:17,696 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:55:17,896 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:55:18,093 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:55:18,288 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:55:18,432 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:55:18,542 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:55:18,661 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:55:18,745 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:55:18,822 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:55:18,914 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:55:19,005 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:55:19,106 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:55:19,218 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:55:19,320 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:55:19,419 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:55:19,549 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:55:19,838 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:55:20,026 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:55:20,171 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:55:20,318 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:55:20,459 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:55:28,511 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:55:28,709 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:55:28,905 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:55:29,103 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:55:29,299 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:55:29,384 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:55:29,486 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:55:29,582 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:55:29,668 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:55:29,770 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:55:29,858 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:55:29,936 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:55:30,006 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:55:30,075 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:55:30,144 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:55:30,216 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:55:30,288 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:55:30,359 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:55:30,430 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:55:30,510 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:55:30,582 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:55:38,571 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:55:38,769 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:55:38,964 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:55:39,092 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:55:39,218 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:55:39,321 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:55:39,433 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:55:39,527 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:55:39,611 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:55:39,703 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:55:39,779 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:55:39,868 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:55:39,963 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:55:40,065 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:55:40,187 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:55:40,292 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:55:40,405 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:55:40,559 - harmonypy - INFO - Converged after 17 iterations
2024-05-29 06:55:49,269 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:55:49,468 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:55:49,664 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:55:49,794 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:55:49,916 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:55:50,029 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:55:50,132 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:55:50,219 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:55:50,297 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:55:50,367 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:55:50,436 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:55:50,515 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:55:50,584 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:55:50,654 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:55:50,734 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:55:50,804 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:55:50,874 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:55:50,944 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:55:51,013 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:55:51,082 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:55:51,152 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:55:59,169 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:55:59,369 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:55:59,562 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:55:59,718 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:55:59,837 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:55:59,981 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:56:00,077 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:56:00,158 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:56:00,236 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:56:00,307 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:56:00,377 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:56:00,446 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:56:00,515 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:56:00,585 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:56:00,655 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:56:00,726 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:56:00,795 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:56:00,864 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:56:00,933 - harmonypy - INFO - Converged after 18 iterations
2024-05-29 06:56:09,154 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:56:09,350 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:56:09,544 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:56:09,736 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:56:09,861 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:56:09,977 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:56:10,084 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:56:10,159 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:56:10,234 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:56:10,300 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:56:10,368 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:56:10,444 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:56:10,518 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:56:10,593 - harmonypy - INFO - Converged after 13 iterations
2024-05-29 06:56:18,639 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:56:18,831 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:56:19,025 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:56:19,216 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:56:19,368 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:56:19,470 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:56:19,570 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:56:19,646 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:56:19,722 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:56:19,822 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:56:19,923 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:56:20,007 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:56:20,074 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:56:20,142 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:56:20,209 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:56:20,277 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:56:20,356 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:56:20,424 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:56:20,492 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:56:20,560 - harmonypy - INFO - Converged after 19 iterations
2024-05-29 06:56:28,676 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:56:28,870 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:56:29,061 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:56:29,187 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:56:29,312 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:56:29,421 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:56:29,537 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:56:29,628 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:56:29,702 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:56:29,769 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:56:29,851 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:56:29,927 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:56:29,995 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:56:30,081 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:56:30,157 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:56:30,228 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:56:30,296 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:56:30,367 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:56:30,435 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:56:30,503 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:56:30,573 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:56:38,822 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:56:39,023 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:56:39,222 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:56:39,420 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:56:39,543 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:56:39,667 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:56:39,773 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:56:39,895 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:56:39,966 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:56:40,040 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:56:40,114 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:56:40,193 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:56:40,273 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:56:40,351 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:56:40,420 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:56:40,498 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:56:40,576 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:56:40,647 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:56:40,720 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:56:40,790 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:56:40,861 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:56:49,795 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:56:50,003 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:56:50,207 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:56:50,359 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:56:50,504 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:56:50,783 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:56:50,891 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:56:50,973 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:56:51,063 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:56:51,156 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:56:51,239 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:56:51,312 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:56:51,404 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:56:51,492 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:56:51,583 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:56:51,663 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:56:51,761 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:56:51,838 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:56:51,912 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:56:51,994 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:56:52,074 - harmonypy - INFO - Stopped before convergence
2024-05-29 06:57:00,325 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:57:00,517 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:57:00,707 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:57:00,900 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:57:01,010 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:57:01,112 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:57:01,196 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:57:01,282 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:57:01,369 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:57:01,470 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:57:01,555 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:57:01,648 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:57:01,724 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:57:01,794 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:57:01,868 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:57:01,934 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:57:02,010 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:57:02,085 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:57:02,152 - harmonypy - INFO - Converged after 18 iterations
2024-05-29 06:57:10,272 - harmonypy - INFO - Iteration 1 of 20
2024-05-29 06:57:10,468 - harmonypy - INFO - Iteration 2 of 20
2024-05-29 06:57:10,659 - harmonypy - INFO - Iteration 3 of 20
2024-05-29 06:57:10,851 - harmonypy - INFO - Iteration 4 of 20
2024-05-29 06:57:10,953 - harmonypy - INFO - Iteration 5 of 20
2024-05-29 06:57:11,070 - harmonypy - INFO - Iteration 6 of 20
2024-05-29 06:57:11,187 - harmonypy - INFO - Iteration 7 of 20
2024-05-29 06:57:11,272 - harmonypy - INFO - Iteration 8 of 20
2024-05-29 06:57:11,347 - harmonypy - INFO - Iteration 9 of 20
2024-05-29 06:57:11,423 - harmonypy - INFO - Iteration 10 of 20
2024-05-29 06:57:11,498 - harmonypy - INFO - Iteration 11 of 20
2024-05-29 06:57:11,566 - harmonypy - INFO - Iteration 12 of 20
2024-05-29 06:57:11,640 - harmonypy - INFO - Iteration 13 of 20
2024-05-29 06:57:11,706 - harmonypy - INFO - Iteration 14 of 20
2024-05-29 06:57:11,781 - harmonypy - INFO - Iteration 15 of 20
2024-05-29 06:57:11,848 - harmonypy - INFO - Iteration 16 of 20
2024-05-29 06:57:11,922 - harmonypy - INFO - Iteration 17 of 20
2024-05-29 06:57:11,997 - harmonypy - INFO - Iteration 18 of 20
2024-05-29 06:57:12,072 - harmonypy - INFO - Iteration 19 of 20
2024-05-29 06:57:12,146 - harmonypy - INFO - Iteration 20 of 20
2024-05-29 06:57:12,229 - harmonypy - INFO - Stopped before convergence
In [32]:
import matplotlib.pyplot as plt
from statsmodels.formula.api import ols
PCRegrDict = {}
npcs = 2
covToTest = ["cellID_newName","leidenAnnotated"]
sns.set_theme(style="ticks")
varianceSummary = pd.DataFrame()
for i in range(npcs):
	adataGenotypes.obsm["X_pca"]
	for n,c in enumerate(covToTest):
		Dummies = pd.get_dummies(adataGenotypes.obs[c])
		PCRegr = (Dummies.T * adataGenotypes.obsm["X_pca"][:,i].T).T.melt()
		PCRegr = PCRegr[PCRegr["value"] != 0]
		PCRegr["variable"] = PCRegr["variable"].astype("category")
		PCRegr["cov"] = c
		PCRegrDict["PC:{}_COV:{}".format(i+1,c)] = PCRegr.copy()
		sns.despine(offset=30)
		PCRegrModel = pd.get_dummies(PCRegrDict["PC:{}_COV:{}".format(i+1,c)], "variable").copy()
		formula = "".join(["value ~ "," + ".join(["C("+c+")" for c in PCRegrModel.columns[1:-1].tolist()])])
		fit = ols(formula, data=PCRegrModel).fit() 
		fit.rsquared_adj
		PCRegr["rsquared_adj"] = fit.rsquared_adj
		PCRegr["PC"] = i
		varianceSummary = pd.concat([varianceSummary,PCRegr ], ignore_index=True)

CovOrder = {i:varianceSummary.drop_duplicates(["PC","cov"])[varianceSummary.drop_duplicates(["PC","cov"])["PC"] == i].sort_values("rsquared_adj", ascending=False)["cov"].tolist() for i in varianceSummary["PC"].unique().tolist()}
for i in range(npcs):
	fig, axes = plt.subplots(1,len(covToTest), figsize=(15,5), dpi=300, sharex=False,sharey=False)
	plt.subplots_adjust(wspace=.5)
	adataGenotypes.obsm["X_pca"]
	for n,c in enumerate(CovOrder[i]):
		PCRegr = varianceSummary[(varianceSummary["PC"] == i) & (varianceSummary["cov"] == c)]
		sns.boxplot(data=PCRegr, x="variable", y="value", ax = axes[n],whis=[0, 100],
			palette={k:ColorDict[c][k] for k in ColorDict[c] if k in PCRegr["variable"].unique().tolist()}, 
			order=[i for i in PlotOrder[c] if i in PCRegr["variable"].unique().tolist()],
			hue_order=[i for i in PlotOrder[c] if i in PCRegr["variable"].unique().tolist()])
		
		sns.stripplot(data=PCRegr, x="variable", y="value", size=4, color=".3",ax = axes[n], 
			order=[i for i in PlotOrder[c] if i in PCRegr["variable"].unique().tolist()],
			hue_order=[i for i in PlotOrder[c] if i in PCRegr["variable"].unique().tolist()])
		axes[n].title.set_text('Covariate:{}'.format(c))
		axes[n].set_xlabel(c, fontsize=20)
		axes[n].set_ylabel("PC{} embeddings".format(i+1), fontsize=20)
		sns.despine(offset=30)
		fit.rsquared_adj = PCRegr["rsquared_adj"].values[0]
		axes[n].text(0.5, 0, "rsquared_adj:{}".format(round(fit.rsquared_adj,2)), horizontalalignment='center', verticalalignment='center',transform=axes[n].transAxes)
		axes[n].tick_params(axis="x", rotation=45)
		plt.xticks(rotation=45)
		fig.autofmt_xdate(rotation=45)
		fig.savefig(figDir+"/8_LineageFigures.Genotypes.leidenID"+branchTag+"PC{}.ExplainedVariance.svg".format(i))
<Figure size 800x800 with 0 Axes>

Tradeseq within lineage¶

In [33]:
plt.rcParams.update(plt.rcParamsDefault)
with open("../data/resources/rcParams.yaml") as f:
    rcParamsDict = yaml.full_load(f)
    for k in rcParamsDict["rcParams"]:
        print("{} {}".format(k,rcParamsDict["rcParams"][k]))
        plt.rcParams[k] = rcParamsDict["rcParams"][k]
    for k1 in set(list(rcParamsDict)).difference(set(["rcParams"])):
        print("{} {}".format(k1,rcParamsDict[k1]))
figure.dpi 80
savefig.dpi 500
figure.figsize [10, 10]
axes.facecolor None
figure.facecolor None
dotSize 20
In [34]:
obs = adataBranch.obs
obsm = adataBranch.obsm


adataTradeseq = sc.read_h5ad(outdir+'/adatas/MultiplexingPreprocessing_unscaled.h5ad')[obs.index]
#Sample extra genes to ensure fair unbyased normalization
ExtraNormGenes = random.sample(adataTradeseq.var_names[~adataTradeseq.var_names.isin(HVGs)].tolist(), len(HVGs.tolist()))
adataTradeseq = adataTradeseq[:,HVGs.tolist()+ExtraNormGenes]

adataTradeseq.obs = obs.loc[adataTradeseq.obs_names]
adataTradeseq = adataTradeseq[:,~adataTradeseq.var_names.str.startswith('MT-')]
adataTradeseq = adataTradeseq[:,~adataTradeseq.var_names.str.startswith(("RPS","RPL"))]
adataTradeseq.obsm = obsm
adataTradeseq.uns["leidenAnnotated_colors"] =  adataBranch[adataTradeseq.obs_names].uns["leidenAnnotated_colors"]


#Trim extreme values of DPT (for potentially low amount of cells)
trimExtremes = [0.01,.99]
minDPT, maxDPT = np.quantile(adataTradeseq.obs["dpt_pseudotime"], trimExtremes)
adataTradeseq = adataTradeseq[(adataTradeseq.obs["dpt_pseudotime"] > minDPT) & (adataTradeseq.obs["dpt_pseudotime"] < maxDPT)]
In [35]:
adataTradeseq.obs[endpoint] = 1
In [36]:
cellWeights = adataTradeseq.obs[endpoint]
cellWeights = np.matrix(cellWeights.to_numpy()).T


pseudotime = adataTradeseq.obs["dpt_pseudotime"]
pseudotime = np.matrix(pseudotime.to_numpy()).T



# Transpose needed!
counts = adataTradeseq.X.T.todense()
counts = counts + abs(counts.min())

varnames = adataTradeseq.var_names.tolist()
In [37]:
import anndata2ri
import rpy2
anndata2ri.activate()
%load_ext rpy2.ipython
The rpy2.ipython extension is already loaded. To reload it, use:
  %reload_ext rpy2.ipython
In [38]:
%%R -i tradeSeqUtilsPath

source(tradeSeqUtilsPath)
In [39]:
%%R -i cellWeights -i pseudotime -i counts -i varnames
set.seed(8)

library(tradeSeq)
library(ggplot2)


w <- as.matrix(cellWeights)
dpt <- as.matrix(pseudotime)
cMatrix <- as.matrix(counts)


gamObj <- fitGAM(cMatrix, verbose = TRUE, pseudotime = dpt, cellWeights = w, nknots = 8, sce=FALSE)
names(gamObj) <- varnames
  |                                                  | 0 % ~calculating   |+                                                 | 1 % ~13m 17s       |+                                                 | 2 % ~12m 42s       |++                                                | 3 % ~12m 16s       |++                                                | 4 % ~12m 21s       |+++                                               | 5 % ~11m 54s       |+++                                               | 6 % ~11m 40s       |++++                                              | 7 % ~11m 28s       |++++                                              | 8 % ~11m 12s       |+++++                                             | 9 % ~11m 04s       |+++++                                             | 10% ~10m 57s       |++++++                                            | 11% ~10m 48s       |++++++                                            | 12% ~10m 40s       |+++++++                                           | 13% ~10m 35s       |+++++++                                           | 14% ~10m 31s       |++++++++                                          | 15% ~10m 24s       |++++++++                                          | 16% ~10m 20s       |+++++++++                                         | 17% ~10m 14s       |+++++++++                                         | 18% ~10m 06s       |++++++++++                                        | 19% ~09m 59s       |++++++++++                                        | 20% ~09m 50s       |+++++++++++                                       | 21% ~09m 47s       |+++++++++++                                       | 22% ~09m 39s       |++++++++++++                                      | 23% ~09m 31s       |++++++++++++                                      | 24% ~09m 21s       |+++++++++++++                                     | 25% ~09m 14s       |+++++++++++++                                     | 26% ~09m 05s       |++++++++++++++                                    | 27% ~08m 58s       |++++++++++++++                                    | 28% ~08m 50s       |+++++++++++++++                                   | 29% ~08m 44s       |+++++++++++++++                                   | 30% ~08m 35s       |++++++++++++++++                                  | 31% ~08m 26s       |++++++++++++++++                                  | 32% ~08m 21s       |+++++++++++++++++                                 | 33% ~08m 14s       |+++++++++++++++++                                 | 34% ~08m 06s       |++++++++++++++++++                                | 35% ~08m 03s       |++++++++++++++++++                                | 36% ~07m 55s       |+++++++++++++++++++                               | 37% ~07m 46s       |+++++++++++++++++++                               | 38% ~07m 39s       |++++++++++++++++++++                              | 39% ~07m 32s       |++++++++++++++++++++                              | 40% ~07m 26s       |+++++++++++++++++++++                             | 41% ~07m 18s       |+++++++++++++++++++++                             | 42% ~07m 11s       |++++++++++++++++++++++                            | 43% ~07m 03s       |++++++++++++++++++++++                            | 44% ~06m 55s       |+++++++++++++++++++++++                           | 45% ~06m 47s       |+++++++++++++++++++++++                           | 46% ~06m 40s       |++++++++++++++++++++++++                          | 47% ~06m 32s       |++++++++++++++++++++++++                          | 48% ~06m 24s       |+++++++++++++++++++++++++                         | 49% ~06m 17s       |+++++++++++++++++++++++++                         | 50% ~06m 11s       |++++++++++++++++++++++++++                        | 51% ~06m 29s       |++++++++++++++++++++++++++                        | 52% ~06m 52s       |+++++++++++++++++++++++++++                       | 53% ~06m 59s       |+++++++++++++++++++++++++++                       | 54% ~07m 09s       |++++++++++++++++++++++++++++                      | 55% ~07m 11s       |++++++++++++++++++++++++++++                      | 56% ~07m 12s       |+++++++++++++++++++++++++++++                     | 57% ~07m 36s       |+++++++++++++++++++++++++++++                     | 58% ~07m 38s       |++++++++++++++++++++++++++++++                    | 59% ~08m 12s       |++++++++++++++++++++++++++++++                    | 60% ~08m 16s       |+++++++++++++++++++++++++++++++                   | 61% ~08m 33s       |+++++++++++++++++++++++++++++++                   | 62% ~08m 33s       |++++++++++++++++++++++++++++++++                  | 63% ~08m 37s       |++++++++++++++++++++++++++++++++                  | 64% ~08m 32s       |+++++++++++++++++++++++++++++++++                 | 65% ~08m 28s       |+++++++++++++++++++++++++++++++++                 | 66% ~08m 16s       |++++++++++++++++++++++++++++++++++                | 67% ~08m 03s       |++++++++++++++++++++++++++++++++++                | 68% ~07m 55s       |+++++++++++++++++++++++++++++++++++               | 69% ~07m 56s       |+++++++++++++++++++++++++++++++++++               | 70% ~07m 44s       |++++++++++++++++++++++++++++++++++++              | 71% ~07m 30s       |++++++++++++++++++++++++++++++++++++              | 72% ~07m 25s       |+++++++++++++++++++++++++++++++++++++             | 73% ~07m 16s       |+++++++++++++++++++++++++++++++++++++             | 74% ~07m 17s       |++++++++++++++++++++++++++++++++++++++            | 75% ~07m 03s       |++++++++++++++++++++++++++++++++++++++            | 76% ~06m 49s       |+++++++++++++++++++++++++++++++++++++++           | 77% ~06m 34s       |+++++++++++++++++++++++++++++++++++++++           | 78% ~06m 19s       |++++++++++++++++++++++++++++++++++++++++          | 79% ~06m 07s       |++++++++++++++++++++++++++++++++++++++++          | 80% ~05m 50s       |+++++++++++++++++++++++++++++++++++++++++         | 81% ~05m 38s       |+++++++++++++++++++++++++++++++++++++++++         | 82% ~05m 20s       |++++++++++++++++++++++++++++++++++++++++++        | 83% ~05m 19s       |++++++++++++++++++++++++++++++++++++++++++        | 84% ~05m 05s       |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~04m 52s       |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~04m 48s       |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~04m 28s       |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~04m 09s       |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~03m 53s       |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~03m 35s       |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~03m 14s       |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~02m 56s       |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~02m 34s       |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~02m 13s       |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~01m 52s       |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~01m 29s       |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~01m 07s       |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~45s           |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~23s           |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=37m 46s
In [40]:
%%R -i tradeSeqUtilsPath

source(tradeSeqUtilsPath)
In [41]:
dptseq = np.linspace(pseudotime.min(),pseudotime.max(), 5)
nGenes = 3

leidenCols = dict(zip(adataTradeseq.obs.leidenAnnotated.cat.categories, adataTradeseq.uns["leidenAnnotated_colors"]))
In [42]:
%%R   -o startRes -i minDPT -i maxDPT


startRes <- startVsEndTest(gamObj, pseudotimeValues = c(minDPT+.01,maxDPT-.01))
In [43]:
# Top Up and Down
startResFilt = startRes[(startRes.pvalue <= 0.001) & (abs(startRes.logFClineage1) >= 2)]
startResFilt["Gene"] = startResFilt.index.tolist()
startResFilt["test"] = "startVsEndTest"
startResGenesPositive = startResFilt[startResFilt.logFClineage1 < 0 ].sort_values(["pvalue","logFClineage1"], ascending=[True,True])
startResGenesPositive_plot = startResGenesPositive.head(nGenes).index.tolist()
startResGenesPositive["PatternType"] = "decreasing"
startResGenesPositive = startResGenesPositive.rename(columns={"logFClineage1":"logFC"})

startResGenesNegatives = startResFilt[startResFilt.logFClineage1 > 0 ].sort_values(["pvalue","logFClineage1"], ascending=[True,False])
startResGenesNegatives_plot = startResGenesNegatives.head(nGenes).index.tolist()
startResGenesNegatives["PatternType"] = "increasing"
startResGenesNegatives = startResGenesNegatives.rename(columns={"logFClineage1":"logFC"})
In [44]:
CombinedDF = pd.concat([startResGenesPositive,startResGenesNegatives], ignore_index=True)
CombinedDF["Branch"] = branchTag
CombinedDF.to_csv(outdir+"/Tradeseq."+branchTag+".tsv", sep="\t", index=False)
In [45]:
%%R  -i startResGenesPositive_plot -i startResGenesNegatives_plot -o assoResSSPandas

CombinedList <- c(startResGenesPositive_plot,startResGenesNegatives_plot)

datalist <- list()
for (g in CombinedList){
    
    localModel <- gamObj[[g]]    
    data <- localModel$model    
    y <- data$y
    nCurves <- length(localModel$smooth)

    for (jj in seq_len(nCurves)) {
        df <- .getPredictRangeDf(localModel$model, jj, nPoints = 100)
        yhat <- predict(localModel, newdata = df, type = "response")

        Newframe <- data.frame("fittedCounts" = yhat)
        colnames(Newframe) <- c(paste0("fittedCounts.",g))

        datalist[[paste(g,jj)]] <- Newframe

        
        

    }

}

assoResSSPandas =  do.call(cbind, datalist)
In [46]:
#Curatedmarkerslist = CuratedmarkersDF.loc[CuratedmarkersDF.score > 1,"name"].tolist()
#CuratedmarkersDF = pd.read_csv(markers, header=None, sep = "\t", names=["name","area","score"])
#Curatedmarkerslist = CuratedmarkersDF.loc[CuratedmarkersDF.score >= 1,"name"].tolist()

##############################


###################à
plt.rcdefaults()

sns.set_style("ticks", {'axes.grid' : False})


fig, axes = plt.subplots(2,1, figsize=(12,5),sharex=True, 
                         gridspec_kw={'height_ratios': [1, 3]})

sns.boxplot(data=adataTradeseq.obs, x="dpt_pseudotime", y="leidenAnnotated", ax = axes[0],
            palette=leidenCols,
            showfliers=False,order=leidenOrder)

    

    
    


#fig, axes = plt.subplots(2,1, figsize=(10,5),sharex=True, 
#                         gridspec_kw={'height_ratios': [1, 2]})

#sns.histplot(data=adataTradeseq.obs, x="dpt_pseudotime", hue="leidenAnnotated", ax=axes[0])

# sns.histplot(data=adataTradeseq.obs, x="dpt_pseudotime", hue="leidenAnnotated", ax=axes[0],bins=100,
#               palette=dict(zip(adata.obs.leidenAnnotated.cat.categories, adata.uns["leidenAnnotated_colors"])), alpha=.5)




SmoothedExpr = assoResSSPandas.copy()
SmoothedExpr["pseudotime"] = SmoothedExpr.index.tolist()      
SmoothedExpr["pseudotime"] =  np.linspace(pseudotime.min(),pseudotime.max(), 100)
SmoothedExpr = SmoothedExpr.melt("pseudotime")
SmoothedExpr["value"] = np.log(SmoothedExpr["value"])


#TrimExtremes


sns.lineplot(data=SmoothedExpr, x="pseudotime", y="value", hue= "variable",  linewidth=3, ax=axes[1])
#axes[1].lines[1].set_linestyle("--")





dptAxis = np.linspace(SmoothedExpr.pseudotime.min(), SmoothedExpr.pseudotime.max(), 10).round(2)      
ylimits = np.array([SmoothedExpr.value.min()-abs((SmoothedExpr.value.min()*.1)), 
                    SmoothedExpr.value.max()+abs((SmoothedExpr.value.max()*.1))]).round(2)
exprAxis = np.linspace(ylimits.min(), ylimits.max(),5).round(2)


axes[1].set_xlim([dptAxis.min(), dptAxis.max()])
axes[1].set_ylim(ylimits)


axes[0].yaxis.tick_right()
axes[0].spines[['left', 'top','bottom']].set_visible(False)
axes[0].spines['right'].set_linewidth(1.5)
axes[0].tick_params(axis='y', which='major', labelsize=15, width=1.5, length=10)
axes[0].tick_params(axis='x', which='major', labelsize=15, width=0, length=10)


axes[1].set_xticks(dptAxis)
axes[1].set_yticks(exprAxis)

axes[1].spines['left'].set_linewidth(1.5)
axes[1].spines['bottom'].set_linewidth(1.5)
axes[1].tick_params(axis='both', which='major', labelsize=15, width=1.5, length=10)
axes[1].spines[['right', 'top']].set_visible(False)
axes[1].xaxis.tick_bottom()
axes[1].yaxis.tick_left()
axes[1].legend(title='Gene', bbox_to_anchor=(1, .7))


sns.despine(ax=axes[1], top=True, right=True, left=False, bottom=False, offset=10, trim=False)
sns.despine(ax=axes[0], top=True, right=False, left=False, bottom=True, offset=10, trim=False)
axes[0].yaxis.set_label_position("right")
axes[0].spines[['left', 'top','bottom']].set_visible(False)

axes[1].set(xlabel='dpt pseudotime', ylabel='Log smoothed expression')



fig.show()
        


fig.savefig(figDir+'/TopGenes.'+branchTag+'.pdf',bbox_inches='tight')

Import VCF and Map snps to genes¶

In [47]:
lineage1 = ["CTL08A","CTL04E"]
lineage2 = ["CTL02A","CTL01"]
In [48]:
def get_vcf_names(vcf_path):
    with open(vcf_path, "rt") as ifile:
          for line in ifile:
            if line.startswith("#CHROM"):
                  vcf_names = [x for x in line.split('\t')]
                  break
    ifile.close()
    return vcf_names

names = [i.replace("#","").replace('\n','') for i in get_vcf_names(vcfPath)] 
mappings = {k: v for d in [{k:iPSC_lines_map[k]["newName"]} for k in list(iPSC_lines_map.keys())] for k, v in d.items()}


vcf = pd.read_csv(vcfPath, sep="\t", skip_blank_lines=True,comment='#', names=names).rename(columns = mappings)
vcf = vcf[~vcf[adataBranch.obs.cellID_newName.unique().tolist()].apply(lambda r: r.str.contains('./.',regex=False).any(), axis=1)]

MappedVars = vcf.copy()
MappedVars["Chromosome"] = "chr"+vcf["CHROM"].astype(str)
MappedVars["End"] = MappedVars["POS"]
MappedVars["Start"] = MappedVars["POS"]
MappedVars = MappedVars[["Chromosome","Start","End","CHROM"]]
MappedVars = pr.PyRanges(MappedVars)
MappedVars

#Prepare gtf for overlap, we exclude non genes features and keep only coding genes
gtf = pd.read_csv(gtfPath, sep="\t", comment='#', header=None)
gtf = gtf[gtf[2] == "gene"]
gtf['GENE'] = gtf[8].str.extract(r'gene_name "(.+?)";')
gtf['GENEtype'] = gtf[8].str.extract(r'gene_type "(.+?)";')
gtf = gtf[gtf['GENEtype'] == "protein_coding"]
gtf = gtf[[0,3,4,"GENE"]]
gtf.columns = ["Chromosome","Start","End","SYMBOL"]
gtf = pr.PyRanges(gtf)
gtf

MappedVars = MappedVars.join(gtf).df.drop_duplicates(subset=["Chromosome","Start","End"]).drop(columns=["Start_b","End_b"])
MappedVars.index = MappedVars["CHROM"].astype(str)+"_"+MappedVars["Start"].astype(str)
MappedVars["indexer"] = MappedVars.index.tolist()

vcf.index  = vcf["CHROM"].astype(str)+"_"+vcf["POS"].astype(str)
MappedVars["REF"] = vcf.loc[MappedVars.index,"REF"]
MappedVars["ALT"] = vcf.loc[MappedVars.index,"ALT"]
In [49]:
# Now we start  refining DF to spot different allelic landscape
LineagesAlleles = vcf[adataBranch.obs.cellID_newName.unique().tolist()]
LineagesAlleles = LineagesAlleles.apply(lambda col: col.str.split(":", expand=True)[0], axis = 0)

L1DF = LineagesAlleles[lineage1].apply(lambda row: set(row.tolist()), axis = 1)
L1DF = L1DF[L1DF.apply(lambda row: len(row)) == 1].to_frame(name = "_".join(lineage1)+"(L1).alleles")
L1DF["_".join(lineage1)+"(L1).alleles"] = L1DF.apply(lambda row: "".join(list(row[0])), axis = 1)


L2DF = LineagesAlleles[lineage2].apply(lambda row: set(row.tolist()), axis = 1)
L2DF = L2DF[L2DF.apply(lambda row: len(row)) == 1].to_frame(name = "_".join(lineage2)+"(L2).alleles")
L2DF["_".join(lineage2)+"(L2).alleles"] = L2DF.apply(lambda row: "".join(list(row[0])), axis = 1)

LineagesAlleles = pd.concat([L1DF,L2DF], axis = 1).dropna()
LineagesAlleles = LineagesAlleles[LineagesAlleles["_".join(lineage1)+"(L1).alleles"] != LineagesAlleles["_".join(lineage2)+"(L2).alleles"]]

LineagesAlleles

LineagesAlleles = LineagesAlleles.join(MappedVars, how="left")
LineagesAlleles["REF"] = vcf.loc[LineagesAlleles.index.tolist(),'REF']
LineagesAlleles["ALT"] = vcf.loc[LineagesAlleles.index.tolist(),'ALT']
LineagesAlleles
Out[49]:
CTL08A_CTL04E(L1).alleles CTL02A_CTL01(L2).alleles Chromosome Start End CHROM SYMBOL indexer REF ALT
1_1728604 0/1 0/0 chr1 1728604.0 1728604.0 1 SLC35E2A 1_1728604 T A
1_6469383 0/0 0/1 chr1 6469383.0 6469383.0 1 PLEKHG5 1_6469383 A G
1_6623180 0/0 0/1 chr1 6623180.0 6623180.0 1 PHF13 1_6623180 G A
1_6635271 0/0 0/1 chr1 6635271.0 6635271.0 1 THAP3 1_6635271 G T
1_11519447 0/1 0/0 chr1 11519447.0 11519447.0 1 DISP3 1_11519447 G C
... ... ... ... ... ... ... ... ... ... ...
X_149482521 0/1 0/0 chrX 149482521.0 149482521.0 X IDS X_149482521 TA TAA,T
X_154473373 1/1 0/0 chrX 154473373.0 154473373.0 X PLXNA3 X_154473373 G A
X_154477925 0/0 1/1 chrX 154477925.0 154477925.0 X LAGE3 X_154477925 C G
X_154484549 1/1 0/0 chrX 154484549.0 154484549.0 X UBL4A X_154484549 T C
X_154506456 1/1 0/0 chrX 154506456.0 154506456.0 X FAM3A X_154506456 A T

1035 rows × 10 columns

Port jerber's eQTL data to hg38¶

In [50]:
def liftOverDF(inDF, chrKey,posKey,indexerKey, oldref="hg19", newref="hg38"):

    lo = LiftOver(oldref, newref)
    


    Liftedvariants = []
    
    __inDF = inDF.copy()
    __inDF[chrKey] = __inDF[chrKey].astype(str)
    
    
    if not __inDF[chrKey].head(1).tolist()[0].startswith("chr"):
        chrRoot = False
        __inDF[chrKey] = "chr"+__inDF[chrKey].astype(str)
    else:
        chrRoot = True
    

    for row in __inDF.index.tolist():

        pos = __inDF.loc[row]
        
        
        posLiftedStart = lo.convert_coordinate(str(pos[chrKey]), pos[posKey])

        if len(posLiftedStart) == 1:

            Liftedvariants.append([posLiftedStart[0][0], posLiftedStart[0][1],  row])
            
    LiftedEnhancers = pd.DataFrame(Liftedvariants, columns=["lifted_"+chrKey,"lifted_"+posKey,"indexRow"])
    LiftedEnhancers.index = LiftedEnhancers["indexRow"]
    
    outDF = pd.merge(__inDF,LiftedEnhancers, how="inner", left_index=True, right_index=True)
    outDF["old_"+chrKey] = outDF[chrKey].astype(str).str.split("chr", expand = True)[1] if not chrRoot else outDF[chrKey]
    outDF["old_"+posKey] = outDF[posKey]
    
    
    outDF[chrKey] = outDF["lifted_"+chrKey].astype(str).str.split("chr", expand = True)[1] if not chrRoot else outDF["lifted_"+chrKey].astype(str)
    outDF[posKey] = outDF["lifted_"+posKey]
    outDF["old_"+indexerKey] = outDF[indexerKey].str.split("chr", expand = True)

    outDF[indexerKey] = outDF[chrKey]+"_"+outDF["lifted_"+posKey].astype(str)
    
    outDF.drop(columns=["lifted_"+chrKey,"lifted_"+posKey], inplace=True)


    return(outDF)
In [51]:
scEqtlsJerber["indexer"] = scEqtlsJerber["snp_chromosome"].astype(str)+"_"+scEqtlsJerber["snp_position"].astype(str)

scEqtlsJerberLifted = liftOverDF(scEqtlsJerber, chrKey="snp_chromosome",posKey="snp_position",indexerKey="indexer", oldref="hg19", newref="hg38")
In [52]:
mergedDFjERBER = scEqtlsJerberLifted[["snp_id","indexer", "assessed_allele", "hgnc_symbol","beta" ]].merge(LineagesAlleles, on="indexer")
In [53]:
mergedDFjERBER
Out[53]:
snp_id indexer assessed_allele hgnc_symbol beta CTL08A_CTL04E(L1).alleles CTL02A_CTL01(L2).alleles Chromosome Start End CHROM SYMBOL REF ALT
0 17_36689228_T_C 17_38532993 C SRCIN1 0.362000 0/0 0/1 chr17 38532993.0 38532993.0 17 SRCIN1 T C
1 17_36689228_T_C 17_38532993 C SRCIN1 0.600568 0/0 0/1 chr17 38532993.0 38532993.0 17 SRCIN1 T C
2 17_36689220_A_G 17_38532985 G SRCIN1 0.788592 0/0 0/1 chr17 38532985.0 38532985.0 17 SRCIN1 A G
3 17_44833217_C_A 17_46755851 A NSF 0.168382 0/1 0/0 chr17 46755851.0 46755851.0 17 NSF C A
4 16_1819433_G_A 16_1769432 A MRPS34 0.229730 0/0 0/1 chr16 1769432.0 1769432.0 16 MAPK8IP3 G A
5 16_1819433_G_A 16_1769432 A MRPS34 0.297822 0/0 0/1 chr16 1769432.0 1769432.0 16 MAPK8IP3 G A
6 20_7962128_C_T 20_7981481 T TMX4 0.576073 0/0 0/1 chr20 7981481.0 7981481.0 20 TMX4 C T
7 7_6502367_T_C 7_6462736 C KDELR2 -0.287541 0/0 0/1 chr7 6462736.0 6462736.0 7 DAGLB T C
8 7_6502367_T_C 7_6462736 C KDELR2 -0.470769 0/0 0/1 chr7 6462736.0 6462736.0 7 DAGLB T C
9 7_6502367_T_C 7_6462736 C KDELR2 -0.410403 0/0 0/1 chr7 6462736.0 6462736.0 7 DAGLB T C
10 7_6502367_T_C 7_6462736 C KDELR2 -0.397031 0/0 0/1 chr7 6462736.0 6462736.0 7 DAGLB T C
11 6_114183884_A_G 6_113862707 G MARCKS -0.088814 0/1 0/0 chr6 113862707.0 113862707.0 6 MARCKS A G
12 3_120114914_G_A 3_120396067 A FSTL1 0.251080 0/1 1/1 chr3 120396067.0 120396067.0 3 FSTL1 G A
13 7_128142023_A_T 7_128501969 T METTL2B -0.243685 0/0 0/1 chr7 128501969.0 128501969.0 7 METTL2B A T
14 3_49052785_T_A 3_49015352 A ARIH2 0.228237 0/1 0/0 chr3 49015352.0 49015352.0 3 WDR6 T A
15 8_144662353_G_A 8_143580183 A MROH6 -0.311070 1/1 0/1 chr8 143580183.0 143580183.0 8 EEF1D G A
In [54]:
print("{} loci found to have different allelic set among the two lineages and previously described as SCeQTLs ".format(len(mergedDFjERBER.indexer.unique())))
11 loci found to have different allelic set among the two lineages and previously described as SCeQTLs 
In [55]:
mergedDFjERBER.to_csv(outdir+"/MatchedSCeQTLs.tsv", sep="\t",index=False )

original snp_id referso to hg19 position that's why the position discrepancy with lifted over coordinates

In [56]:
# Check among sceqtl genes the ones relevant (HVGs) for the isolated branch
In [57]:
set(mergedDFjERBER.hgnc_symbol).intersection(set(TopLoadings.index.tolist()))
Out[57]:
{'SRCIN1'}

Check variance for SRCIN1¶

In [58]:
TopLoadings["rank"] = TopLoadings["loading"].rank()
TopLoadings["Zero"] = 0
In [59]:
#if you want vector sc.settings._vector_friendly = False
sns.set_style("ticks")
vector=True
n=20
pdDict = {}
pylab.rcParams['figure.figsize'] = (10, 10)

if vector:
    sc.settings._vector_friendly = False
for pc in  [0,1]:
    TopPC_IDX = np.argpartition(adataBranch.varm["PCs"][:,pc], -n)[-n:]
    DownPC_IDX = np.argpartition(adataBranch.varm["PCs"][:,pc], n)[:n]
    pdDict[pc] = pd.DataFrame(adataBranch.varm["PCs"][:,pc][TopPC_IDX], index = adataBranch.var_names[TopPC_IDX], columns=["pc"+str(pc+1)])
    pdDict[pc] = pd.concat([pdDict[pc],pd.DataFrame(adataBranch.varm["PCs"][:,pc][DownPC_IDX], index = adataBranch.var_names[DownPC_IDX], columns=["pc"+str(pc+1)])])
    pdDict[pc]["gene"] = pdDict[pc].index.tolist()
    if pc == 0:
        pdDict[pc] = pdDict[pc].sort_values("pc"+str(pc+1))
    elif pc == 1:
        pdDict[pc] = pdDict[pc].sort_values("pc"+str(pc+1), ascending = False)
    
    
    

figsize = (6, 6)  #(width, height)
#Set axes
import matplotlib.pyplot as plt

fig, ax = plt.subplots(nrows=2, ncols=1, figsize=figsize,gridspec_kw={'height_ratios': [3, 1]})

fig.tight_layout(pad=-2, h_pad=0)   #space between plots

ax1plot = sc.pl.pca(adataBranch, components=['1,2'], color=["leidenAnnotated"], 
                    ncols=1, add_outline=True, legend_loc="on data",size=100,legend_fontsize="small",
                    outline_width=(.1,.05), wspace=.2, show=False, ax=ax[0])



colors = [plt.cm.RdYlGn(norm(c)) for c in TopLoadings["loading"]]
sns.scatterplot(data=TopLoadings, x="rank", y="loading", linewidth=0, hue = "rank",palette=colors, size=.1, ax=ax[1], alpha=1)

for i in ["SRCIN1","TOP2A","LHX1"]:
    offsety =  -.05 if TopLoadings.loc[i,"loading"] > 0 else .05
    offsetx =  -100 if TopLoadings.loc[i,"loading"] > 0 else 100
    ax[1].annotate(i, 
                xy=(TopLoadings.loc[i,"rank"],TopLoadings.loc[i,"loading"]),
                xytext=(TopLoadings.loc[i,"rank"] + offsetx, offsety),
    xycoords='data',
    arrowprops=dict(arrowstyle="simple",facecolor="black",))

ax[1].get_legend().remove()




sc.settings._vector_friendly = True
pylab.rcParams['figure.figsize'] = (4, 4)
In [60]:
fig.savefig(figDir+"/SRCINlloadings.PCA.pdf",
           bbox_inches="tight")

genomic plot¶

In [61]:
mergedDFjERBER.drop_duplicates("indexer")
Out[61]:
snp_id indexer assessed_allele hgnc_symbol beta CTL08A_CTL04E(L1).alleles CTL02A_CTL01(L2).alleles Chromosome Start End CHROM SYMBOL REF ALT
0 17_36689228_T_C 17_38532993 C SRCIN1 0.362000 0/0 0/1 chr17 38532993.0 38532993.0 17 SRCIN1 T C
2 17_36689220_A_G 17_38532985 G SRCIN1 0.788592 0/0 0/1 chr17 38532985.0 38532985.0 17 SRCIN1 A G
3 17_44833217_C_A 17_46755851 A NSF 0.168382 0/1 0/0 chr17 46755851.0 46755851.0 17 NSF C A
4 16_1819433_G_A 16_1769432 A MRPS34 0.229730 0/0 0/1 chr16 1769432.0 1769432.0 16 MAPK8IP3 G A
6 20_7962128_C_T 20_7981481 T TMX4 0.576073 0/0 0/1 chr20 7981481.0 7981481.0 20 TMX4 C T
7 7_6502367_T_C 7_6462736 C KDELR2 -0.287541 0/0 0/1 chr7 6462736.0 6462736.0 7 DAGLB T C
11 6_114183884_A_G 6_113862707 G MARCKS -0.088814 0/1 0/0 chr6 113862707.0 113862707.0 6 MARCKS A G
12 3_120114914_G_A 3_120396067 A FSTL1 0.251080 0/1 1/1 chr3 120396067.0 120396067.0 3 FSTL1 G A
13 7_128142023_A_T 7_128501969 T METTL2B -0.243685 0/0 0/1 chr7 128501969.0 128501969.0 7 METTL2B A T
14 3_49052785_T_A 3_49015352 A ARIH2 0.228237 0/1 0/0 chr3 49015352.0 49015352.0 3 WDR6 T A
15 8_144662353_G_A 8_143580183 A MROH6 -0.311070 1/1 0/1 chr8 143580183.0 143580183.0 8 EEF1D G A
In [62]:
fig, ax = plt.subplots(nrows=1, ncols= len(mergedDFjERBER.CHROM.unique()), 
                       figsize= (5,2),gridspec_kw={'width_ratios': mergedDFjERBER.drop_duplicates("indexer").groupby("CHROM").size()[mergedDFjERBER.CHROM.unique()].tolist()},
                       sharex=False, sharey=True)

fig.tight_layout(h_pad=30000)

for chrom in zip(mergedDFjERBER.CHROM.unique(),ax ):
    chromMerged = mergedDFjERBER.loc[mergedDFjERBER.CHROM == chrom[0], ["Chromosome","Start", "CTL08A_CTL04E(L1).alleles","CTL02A_CTL01(L2).alleles","indexer"]]
    chromMerged = chromMerged.drop_duplicates("indexer")
    chromMerged = chromMerged.drop(columns="indexer")
    chromMerged = chromMerged.melt(["Start","Chromosome"])
    chromMerged["RankedPosition"] = chromMerged["Start"].rank()
    chromMerged = chromMerged.sort_values("RankedPosition")
    
    chromMerged = pd.concat([chromMerged.assign(Symbol=8).assign(genotype=chromMerged.variable.str.split("_", expand=True)[0]),chromMerged.assign(Symbol=9).assign(genotype=chromMerged.variable.str.split("_", expand=True)[1].str.split("(", expand=True)[0])], axis = 0, ignore_index=True)
    

    

    chromMerged["value"] = chromMerged.value.astype("category")
    sns.scatterplot(data=chromMerged, x = "RankedPosition" , y = "value", hue="genotype",
                    ax=chrom[1], s=80,linewidth=0,edgecolor="black", palette=cellIDColorsMap, 
                    style="Symbol", markers=dict(zip(chromMerged.Symbol, chromMerged.Symbol)))
    chrom[1].get_legend().remove()
    chrom[1].set_xticks(chromMerged["RankedPosition"].unique().tolist())
    
    
    
    chrom[1].set_xticklabels(["chr"+str(chrom[0])+":"+ str(Start) for Start in chromMerged["Start"].astype(int).unique().tolist()],rotation=45, fontsize=7)
    chrom[1].tick_params(left=False)
    chrom[1].spines[['left', 'top','right']].set_visible(False)
    chrom[1].set_xlim([chromMerged["RankedPosition"].min(), chromMerged["RankedPosition"].max()])
    chrom[1].set_xlabel(xlabel="Position \n (Chrom_"+str(chrom[0])+")", fontsize = 6)
    chrom[1].set_ylabel(ylabel="Genotype", fontsize = 6)


fig.savefig(figDir+'/DifferentAlleles.pdf',bbox_inches='tight')

Number of overlapping variants¶

1) Number of eVARs in jerber et al¶

In [66]:
print(len(scEqtlsJerber.indexer.unique().tolist()))
10972

2) Number of Multiplexing project variants after filtering¶

In [72]:
vcf.shape[0]
Out[72]:
24987

3) Number of Multiplexing project variants that divide the 2 genotypes groups¶

In [71]:
print(LineagesAlleles.shape[0])
1035

3) Number of overlapping variants between 1 and 3¶

In [74]:
# Number of overlapping variants between 
print(mergedDFjERBER.drop_duplicates("indexer").shape[0])
11